@@ -94,22 +94,19 @@ public class GroupsAction implements UsersWsAction { | |||
.pageSize(pageSize) | |||
.build(); | |||
DbSession session = dbClient.openSession(false); | |||
try { | |||
UserDto user = dbClient.userDao().selectByLogin(session, login); | |||
try (DbSession dbSession = dbClient.openSession(false)) { | |||
UserDto user = dbClient.userDao().selectByLogin(dbSession, login); | |||
if (user == null) { | |||
throw new NotFoundException(String.format("User with login '%s' has not been found", login)); | |||
} | |||
int total = dbClient.groupMembershipDao().countGroups(session, query, user.getId()); | |||
int total = dbClient.groupMembershipDao().countGroups(dbSession, query, user.getId()); | |||
Paging paging = forPageIndex(page).withPageSize(pageSize).andTotal(total); | |||
List<GroupMembershipDto> groups = dbClient.groupMembershipDao().selectGroups(session, query, user.getId(), paging.offset(), pageSize); | |||
List<GroupMembershipDto> groups = dbClient.groupMembershipDao().selectGroups(dbSession, query, user.getId(), paging.offset(), pageSize); | |||
JsonWriter json = response.newJsonWriter().beginObject(); | |||
writeGroups(json, groups); | |||
writePaging(json, paging); | |||
json.endObject().close(); | |||
} finally { | |||
session.close(); | |||
} | |||
} | |||
@@ -19,7 +19,6 @@ | |||
*/ | |||
package org.sonar.server.usergroups.ws; | |||
import java.util.Arrays; | |||
import org.sonar.api.server.ws.Request; | |||
import org.sonar.api.server.ws.Response; | |||
import org.sonar.api.server.ws.WebService.NewAction; | |||
@@ -27,30 +26,28 @@ import org.sonar.api.server.ws.WebService.NewController; | |||
import org.sonar.core.permission.GlobalPermissions; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.user.GroupDto; | |||
import org.sonar.db.user.UserDto; | |||
import org.sonar.db.user.UserGroupDto; | |||
import org.sonar.server.exceptions.NotFoundException; | |||
import org.sonar.server.user.UserSession; | |||
import static java.lang.String.format; | |||
import static org.sonar.db.MyBatis.closeQuietly; | |||
import static org.sonar.server.usergroups.ws.UserGroupsWsParameters.PARAM_GROUP_ID; | |||
import static org.sonar.server.usergroups.ws.UserGroupsWsParameters.PARAM_GROUP_NAME; | |||
import static org.sonar.server.usergroups.ws.UserGroupsWsParameters.PARAM_LOGIN; | |||
import static org.sonar.server.usergroups.ws.UserGroupsWsParameters.createGroupParameters; | |||
import static org.sonar.server.usergroups.ws.UserGroupsWsParameters.createLoginParameter; | |||
import static org.sonar.server.usergroups.ws.GroupWsSupport.PARAM_GROUP_ID; | |||
import static org.sonar.server.usergroups.ws.GroupWsSupport.PARAM_GROUP_NAME; | |||
import static org.sonar.server.usergroups.ws.GroupWsSupport.PARAM_LOGIN; | |||
import static org.sonar.server.usergroups.ws.GroupWsSupport.defineGroupWsParameters; | |||
import static org.sonar.server.usergroups.ws.GroupWsSupport.defineLoginWsParameter; | |||
public class AddUserAction implements UserGroupsWsAction { | |||
private final DbClient dbClient; | |||
private final UserGroupFinder userGroupFinder; | |||
private final UserSession userSession; | |||
private final GroupWsSupport support; | |||
public AddUserAction(DbClient dbClient, UserGroupFinder userGroupFinder, UserSession userSession) { | |||
public AddUserAction(DbClient dbClient, UserSession userSession, GroupWsSupport support) { | |||
this.dbClient = dbClient; | |||
this.userGroupFinder = userGroupFinder; | |||
this.userSession = userSession; | |||
this.support = support; | |||
} | |||
@Override | |||
@@ -62,40 +59,34 @@ public class AddUserAction implements UserGroupsWsAction { | |||
.setPost(true) | |||
.setSince("5.2"); | |||
createGroupParameters(action); | |||
createLoginParameter(action); | |||
defineGroupWsParameters(action); | |||
defineLoginWsParameter(action); | |||
} | |||
@Override | |||
public void handle(Request request, Response response) throws Exception { | |||
userSession.checkLoggedIn().checkPermission(GlobalPermissions.SYSTEM_ADMIN); | |||
WsGroupRef wsGroupRef = WsGroupRef.newWsGroupRefFromUserGroupRequest(request); | |||
String login = request.mandatoryParam(PARAM_LOGIN); | |||
DbSession dbSession = dbClient.openSession(false); | |||
try { | |||
GroupDto group = userGroupFinder.getGroup(dbSession, wsGroupRef); | |||
try (DbSession dbSession = dbClient.openSession(false)) { | |||
GroupId groupId = support.findGroup(dbSession, request); | |||
String login = request.mandatoryParam(PARAM_LOGIN); | |||
UserDto user = dbClient.userDao().selectActiveUserByLogin(dbSession, login); | |||
if (user == null) { | |||
throw new NotFoundException(format("Could not find a user with login '%s'", login)); | |||
} | |||
if (userIsNotYetMemberOf(dbSession, login, group)) { | |||
UserGroupDto userGroup = new UserGroupDto().setGroupId(group.getId()).setUserId(user.getId()); | |||
dbClient.userGroupDao().insert(dbSession, userGroup); | |||
if (userIsNotYetMemberOf(dbSession, user.getId(), groupId)) { | |||
UserGroupDto membershipDto = new UserGroupDto().setGroupId(groupId.getId()).setUserId(user.getId()); | |||
dbClient.userGroupDao().insert(dbSession, membershipDto); | |||
dbSession.commit(); | |||
} | |||
response.noContent(); | |||
} finally { | |||
closeQuietly(dbSession); | |||
} | |||
} | |||
private boolean userIsNotYetMemberOf(DbSession dbSession, String login, GroupDto group) { | |||
return !dbClient.groupMembershipDao().selectGroupsByLogins(dbSession, Arrays.asList(login)).get(login).contains(group.getName()); | |||
private boolean userIsNotYetMemberOf(DbSession dbSession, long userId, GroupId groupId) { | |||
return !dbClient.groupMembershipDao().selectGroupIdsByUserId(dbSession, userId).contains(groupId.getId()); | |||
} | |||
} |
@@ -23,47 +23,56 @@ import org.sonar.api.server.ws.Request; | |||
import org.sonar.api.server.ws.Response; | |||
import org.sonar.api.server.ws.WebService.NewAction; | |||
import org.sonar.api.server.ws.WebService.NewController; | |||
import org.sonar.api.utils.text.JsonWriter; | |||
import org.sonar.api.user.UserGroupValidation; | |||
import org.sonar.core.permission.GlobalPermissions; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.organization.OrganizationDto; | |||
import org.sonar.db.user.GroupDto; | |||
import org.sonar.server.user.UserSession; | |||
import org.sonarqube.ws.WsUserGroups; | |||
import static org.sonar.api.user.UserGroupValidation.GROUP_NAME_MAX_LENGTH; | |||
import static org.sonar.db.MyBatis.closeQuietly; | |||
import static org.sonar.server.usergroups.ws.UserGroupUpdater.DESCRIPTION_MAX_LENGTH; | |||
import static org.sonar.server.usergroups.ws.UserGroupUpdater.PARAM_DESCRIPTION; | |||
import static org.sonar.server.usergroups.ws.UserGroupUpdater.PARAM_NAME; | |||
import static org.sonar.server.usergroups.ws.GroupWsSupport.DESCRIPTION_MAX_LENGTH; | |||
import static org.sonar.server.usergroups.ws.GroupWsSupport.PARAM_GROUP_DESCRIPTION; | |||
import static org.sonar.server.usergroups.ws.GroupWsSupport.PARAM_GROUP_NAME; | |||
import static org.sonar.server.usergroups.ws.GroupWsSupport.PARAM_ORGANIZATION_KEY; | |||
import static org.sonar.server.usergroups.ws.GroupWsSupport.toProtobuf; | |||
import static org.sonar.server.ws.WsUtils.writeProtobuf; | |||
public class CreateAction implements UserGroupsWsAction { | |||
private final DbClient dbClient; | |||
private final UserSession userSession; | |||
private final UserGroupUpdater groupUpdater; | |||
private final GroupWsSupport support; | |||
public CreateAction(DbClient dbClient, UserSession userSession, UserGroupUpdater groupUpdater) { | |||
public CreateAction(DbClient dbClient, UserSession userSession, GroupWsSupport support) { | |||
this.dbClient = dbClient; | |||
this.groupUpdater = groupUpdater; | |||
this.userSession = userSession; | |||
this.support = support; | |||
} | |||
@Override | |||
public void define(NewController context) { | |||
NewAction action = context.createAction("create") | |||
public void define(NewController controller) { | |||
NewAction action = controller.createAction("create") | |||
.setDescription("Create a group.") | |||
.setHandler(this) | |||
.setPost(true) | |||
.setResponseExample(getClass().getResource("example-create.json")) | |||
.setSince("5.2"); | |||
action.createParam(PARAM_NAME) | |||
action.createParam(PARAM_ORGANIZATION_KEY) | |||
.setDescription("Key of organization. If unset then default organization is used.") | |||
.setExampleValue("my-org") | |||
.setSince("6.2"); | |||
action.createParam(PARAM_GROUP_NAME) | |||
.setDescription(String.format("Name for the new group. A group name cannot be larger than %d characters and must be unique. " + | |||
"The value 'anyone' (whatever the case) is reserved and cannot be used.", GROUP_NAME_MAX_LENGTH)) | |||
.setExampleValue("sonar-users") | |||
.setRequired(true); | |||
action.createParam(PARAM_DESCRIPTION) | |||
action.createParam(PARAM_GROUP_DESCRIPTION) | |||
.setDescription(String.format("Description for the new group. A group description cannot be larger than %d characters.", DESCRIPTION_MAX_LENGTH)) | |||
.setExampleValue("Default group for new users"); | |||
} | |||
@@ -72,25 +81,28 @@ public class CreateAction implements UserGroupsWsAction { | |||
public void handle(Request request, Response response) throws Exception { | |||
userSession.checkLoggedIn().checkPermission(GlobalPermissions.SYSTEM_ADMIN); | |||
String name = request.mandatoryParam(PARAM_NAME); | |||
String description = request.param(PARAM_DESCRIPTION); | |||
try (DbSession dbSession = dbClient.openSession(false)) { | |||
OrganizationDto organization = support.findOrganizationByKey(dbSession, request.param(PARAM_ORGANIZATION_KEY)); | |||
GroupDto group = new GroupDto() | |||
.setOrganizationUuid(organization.getUuid()) | |||
.setName(request.mandatoryParam(PARAM_GROUP_NAME)) | |||
.setDescription(request.param(PARAM_GROUP_DESCRIPTION)); | |||
groupUpdater.validateName(name); | |||
if (description != null) { | |||
groupUpdater.validateDescription(description); | |||
} | |||
// validations | |||
UserGroupValidation.validateGroupName(group.getName()); | |||
support.validateDescription(group.getDescription()); | |||
support.checkNameDoesNotExist(dbSession, group.getOrganizationUuid(), group.getName()); | |||
DbSession session = dbClient.openSession(false); | |||
try { | |||
groupUpdater.checkNameIsUnique(name, session); | |||
GroupDto newGroup = dbClient.groupDao().insert(session, new GroupDto().setName(name).setDescription(description)); | |||
session.commit(); | |||
dbClient.groupDao().insert(dbSession, group); | |||
dbSession.commit(); | |||
JsonWriter json = response.newJsonWriter().beginObject(); | |||
groupUpdater.writeGroup(json, newGroup, 0); | |||
json.endObject().close(); | |||
} finally { | |||
closeQuietly(session); | |||
writeResponse(request, response, organization, group); | |||
} | |||
} | |||
private void writeResponse(Request request, Response response, OrganizationDto organization, GroupDto group) { | |||
WsUserGroups.CreateResponse.Builder respBuilder = WsUserGroups.CreateResponse.newBuilder(); | |||
respBuilder.setGroup(toProtobuf(organization, group, 0)); | |||
writeProtobuf(respBuilder.build(), request, response); | |||
} | |||
} |
@@ -19,6 +19,7 @@ | |||
*/ | |||
package org.sonar.server.usergroups.ws; | |||
import java.util.Optional; | |||
import org.sonar.api.CoreProperties; | |||
import org.sonar.api.config.Settings; | |||
import org.sonar.api.server.ws.Request; | |||
@@ -28,28 +29,32 @@ import org.sonar.api.server.ws.WebService.NewController; | |||
import org.sonar.core.permission.GlobalPermissions; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.MyBatis; | |||
import org.sonar.db.permission.PermissionQuery; | |||
import org.sonar.db.user.GroupDto; | |||
import org.sonar.server.organization.DefaultOrganizationProvider; | |||
import org.sonar.server.user.UserSession; | |||
import static com.google.common.base.Preconditions.checkArgument; | |||
import static java.lang.String.format; | |||
import static org.sonar.server.usergroups.ws.UserGroupsWsParameters.PARAM_GROUP_ID; | |||
import static org.sonar.server.usergroups.ws.UserGroupsWsParameters.PARAM_GROUP_NAME; | |||
import static org.sonar.server.usergroups.ws.GroupWsSupport.PARAM_GROUP_ID; | |||
import static org.sonar.server.usergroups.ws.GroupWsSupport.PARAM_GROUP_NAME; | |||
import static org.sonar.server.usergroups.ws.GroupWsSupport.defineGroupWsParameters; | |||
public class DeleteAction implements UserGroupsWsAction { | |||
private final DbClient dbClient; | |||
private final UserGroupFinder userGroupFinder; | |||
private final UserSession userSession; | |||
private final GroupWsSupport support; | |||
private final Settings settings; | |||
private final DefaultOrganizationProvider defaultOrganizationProvider; | |||
public DeleteAction(DbClient dbClient, UserGroupFinder userGroupFinder, UserSession userSession, Settings settings) { | |||
public DeleteAction(DbClient dbClient, UserSession userSession, GroupWsSupport support, Settings settings, | |||
DefaultOrganizationProvider defaultOrganizationProvider) { | |||
this.dbClient = dbClient; | |||
this.userGroupFinder = userGroupFinder; | |||
this.userSession = userSession; | |||
this.support = support; | |||
this.settings = settings; | |||
this.defaultOrganizationProvider = defaultOrganizationProvider; | |||
} | |||
@Override | |||
@@ -63,62 +68,65 @@ public class DeleteAction implements UserGroupsWsAction { | |||
.setSince("5.2") | |||
.setPost(true); | |||
UserGroupsWsParameters.createGroupParameters(action); | |||
defineGroupWsParameters(action); | |||
} | |||
@Override | |||
public void handle(Request request, Response response) throws Exception { | |||
userSession.checkLoggedIn().checkPermission(GlobalPermissions.SYSTEM_ADMIN); | |||
WsGroupRef groupRef = WsGroupRef.newWsGroupRefFromUserGroupRequest(request); | |||
DbSession dbSession = dbClient.openSession(false); | |||
try { | |||
GroupDto group = userGroupFinder.getGroup(dbSession, groupRef); | |||
long groupId = group.getId(); | |||
try (DbSession dbSession = dbClient.openSession(false)) { | |||
GroupId groupId = support.findGroup(dbSession, request); | |||
checkNotTryingToDeleteDefaultGroup(dbSession, groupId); | |||
checkNotTryingToDeleteLastSystemAdminGroup(dbSession, group.getName()); | |||
checkNotTryingToDeleteLastSystemAdminGroup(dbSession, groupId); | |||
removeGroupMembers(dbSession, groupId); | |||
removeGroupPermissions(dbSession, groupId); | |||
removeFromPermissionTemplates(dbSession, groupId); | |||
dbClient.groupDao().deleteById(dbSession, groupId); | |||
dbClient.groupDao().deleteById(dbSession, groupId.getId()); | |||
dbSession.commit(); | |||
response.noContent(); | |||
} finally { | |||
MyBatis.closeQuietly(dbSession); | |||
} | |||
} | |||
private void checkNotTryingToDeleteDefaultGroup(DbSession dbSession, long groupId) { | |||
/** | |||
* The property "default group" is used when registering a new user so that | |||
* he automatically becomes a member of this group. This feature does not | |||
* not exist on non-default organizations yet as organization settings | |||
* are not implemented. | |||
*/ | |||
private void checkNotTryingToDeleteDefaultGroup(DbSession dbSession, GroupId group) { | |||
String defaultGroupName = settings.getString(CoreProperties.CORE_DEFAULT_GROUP); | |||
GroupDto defaultGroup = dbClient.groupDao().selectOrFailByName(dbSession, defaultGroupName); | |||
checkArgument(groupId != defaultGroup.getId(), | |||
format("Default group '%s' cannot be deleted", defaultGroupName)); | |||
if (defaultGroupName != null && group.getOrganizationUuid().equals(defaultOrganizationProvider.get().getUuid())) { | |||
Optional<GroupDto> defaultGroup = dbClient.groupDao().selectByName(dbSession, group.getOrganizationUuid(), defaultGroupName); | |||
checkArgument(!defaultGroup.isPresent() || defaultGroup.get().getId() != group.getId(), | |||
format("Default group '%s' cannot be deleted", defaultGroupName)); | |||
} | |||
} | |||
private void checkNotTryingToDeleteLastSystemAdminGroup(DbSession dbSession, String groupName) { | |||
boolean hasAdminPermission = dbClient.roleDao() | |||
.selectGroupPermissions(dbSession, groupName, null) | |||
private void checkNotTryingToDeleteLastSystemAdminGroup(DbSession dbSession, GroupId group) { | |||
boolean hasAdminPermission = dbClient.groupPermissionDao() | |||
.selectGroupPermissions(dbSession, group.getId(), null) | |||
.contains(GlobalPermissions.SYSTEM_ADMIN); | |||
// TODO support organizations | |||
boolean isOneRemainingAdminGroup = dbClient.groupPermissionDao().countGroups(dbSession, GlobalPermissions.SYSTEM_ADMIN, null) == 1; | |||
boolean hasNoStandaloneAdminUser = dbClient.userPermissionDao().countUsers(dbSession, | |||
PermissionQuery.builder().setPermission(GlobalPermissions.SYSTEM_ADMIN).withAtLeastOnePermission().build()) == 0; | |||
boolean isLastAdminGroup = hasAdminPermission && isOneRemainingAdminGroup && hasNoStandaloneAdminUser; | |||
checkArgument(!isLastAdminGroup, "The last system admin group '%s' cannot be deleted", groupName); | |||
checkArgument(!isLastAdminGroup, "The last system admin group cannot be deleted"); | |||
} | |||
private void removeGroupMembers(DbSession dbSession, long groupId) { | |||
dbClient.userGroupDao().deleteMembersByGroupId(dbSession, groupId); | |||
private void removeGroupMembers(DbSession dbSession, GroupId groupId) { | |||
dbClient.userGroupDao().deleteByGroupId(dbSession, groupId.getId()); | |||
} | |||
private void removeGroupPermissions(DbSession dbSession, long groupId) { | |||
dbClient.roleDao().deleteGroupRolesByGroupId(dbSession, groupId); | |||
private void removeGroupPermissions(DbSession dbSession, GroupId groupId) { | |||
dbClient.roleDao().deleteGroupRolesByGroupId(dbSession, groupId.getId()); | |||
} | |||
private void removeFromPermissionTemplates(DbSession dbSession, long groupId) { | |||
dbClient.permissionTemplateDao().deleteByGroup(dbSession, groupId); | |||
private void removeFromPermissionTemplates(DbSession dbSession, GroupId groupId) { | |||
dbClient.permissionTemplateDao().deleteByGroup(dbSession, groupId.getId()); | |||
} | |||
} |
@@ -19,35 +19,38 @@ | |||
*/ | |||
package org.sonar.server.usergroups.ws; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import javax.annotation.concurrent.Immutable; | |||
import org.sonar.db.user.GroupDto; | |||
import static org.sonar.server.ws.WsUtils.checkFound; | |||
import static java.util.Objects.requireNonNull; | |||
public class UserGroupFinder { | |||
private final DbClient dbClient; | |||
public UserGroupFinder(DbClient dbClient) { | |||
this.dbClient = dbClient; | |||
} | |||
/** | |||
* Reference to a user group, as used internally by the backend. It does | |||
* not support reference to virtual groups "anyone". | |||
* | |||
* @see GroupWsRef | |||
* @see GroupIdOrAnyone | |||
*/ | |||
@Immutable | |||
public class GroupId { | |||
public GroupDto getGroup(DbSession dbSession, WsGroupRef group) { | |||
Long groupId = group.id(); | |||
String groupName = group.name(); | |||
private final long id; | |||
private final String organizationUuid; | |||
GroupDto groupDto = null; | |||
public GroupId(String organizationUuid, long id) { | |||
this.id = id; | |||
this.organizationUuid = requireNonNull(organizationUuid); | |||
} | |||
if (groupId != null) { | |||
groupDto = checkFound(dbClient.groupDao().selectById(dbSession, groupId), | |||
"Group with id '%d' is not found", groupId); | |||
} | |||
public long getId() { | |||
return id; | |||
} | |||
if (groupName != null) { | |||
groupDto = checkFound(dbClient.groupDao().selectByName(dbSession, groupName), | |||
"Group with name '%s' is not found", groupName); | |||
} | |||
public String getOrganizationUuid() { | |||
return organizationUuid; | |||
} | |||
return groupDto; | |||
public static GroupId from(GroupDto dto) { | |||
return new GroupId(dto.getOrganizationUuid(), dto.getId()); | |||
} | |||
} |
@@ -0,0 +1,73 @@ | |||
/* | |||
* 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 org.sonar.server.usergroups.ws; | |||
import javax.annotation.CheckForNull; | |||
import javax.annotation.Nullable; | |||
import javax.annotation.concurrent.Immutable; | |||
import org.sonar.db.user.GroupDto; | |||
import static java.util.Objects.requireNonNull; | |||
/** | |||
* Reference to a user group, as used internally by the backend. Contrary to | |||
* {@link GroupId}, it supports reference to virtual groups "anyone". In these | |||
* cases {@link #getId()} returns {@code null} | |||
* | |||
* @see GroupWsRef | |||
* @see GroupId | |||
*/ | |||
@Immutable | |||
public class GroupIdOrAnyone { | |||
private final Long id; | |||
private final String organizationUuid; | |||
public GroupIdOrAnyone(String organizationUuid, @Nullable Long id) { | |||
this.id = id; | |||
this.organizationUuid = requireNonNull(organizationUuid); | |||
} | |||
public GroupIdOrAnyone(GroupDto group) { | |||
this.id = requireNonNull(group.getId()); | |||
this.organizationUuid = requireNonNull(group.getOrganizationUuid()); | |||
} | |||
public boolean isAnyone() { | |||
return id == null; | |||
} | |||
@CheckForNull | |||
public Long getId() { | |||
return id; | |||
} | |||
public String getOrganizationUuid() { | |||
return organizationUuid; | |||
} | |||
public static GroupIdOrAnyone from(GroupDto dto) { | |||
return new GroupIdOrAnyone(dto.getOrganizationUuid(), dto.getId()); | |||
} | |||
public static GroupIdOrAnyone forAnyone(String organizationUuid) { | |||
return new GroupIdOrAnyone(organizationUuid, null); | |||
} | |||
} |
@@ -0,0 +1,163 @@ | |||
/* | |||
* 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 org.sonar.server.usergroups.ws; | |||
import javax.annotation.CheckForNull; | |||
import javax.annotation.Nullable; | |||
import javax.annotation.concurrent.Immutable; | |||
import org.sonar.api.security.DefaultGroups; | |||
import static com.google.common.base.Preconditions.checkArgument; | |||
import static com.google.common.base.Preconditions.checkState; | |||
import static java.util.Objects.requireNonNull; | |||
import static org.sonar.server.ws.WsUtils.checkRequest; | |||
/** | |||
* Reference to a user group <b>as declared by web service requests</b>. It is one, and only one, | |||
* of these two options: | |||
* <ul> | |||
* <li>group id, for instance 1234</li> | |||
* <li>group name and optional organization key</li> | |||
* </ul> | |||
* | |||
* The reference is then converted to a {@link GroupId} or {@link GroupIdOrAnyone}. | |||
*/ | |||
@Immutable | |||
public class GroupWsRef { | |||
private static final int NULL_ID = -1; | |||
private final long id; | |||
private final String organizationKey; | |||
private final String name; | |||
private GroupWsRef(long id, @Nullable String organizationKey, @Nullable String name) { | |||
this.id = id; | |||
this.organizationKey = organizationKey; | |||
this.name = name; | |||
} | |||
/** | |||
* @return {@code true} if id is defined and {@link #getId()} can be called. If {@code false}, then | |||
* the couple {organizationKey, name} is defined and the methods {@link #getOrganizationKey()}/{@link #getName()} | |||
* can be called. | |||
*/ | |||
public boolean hasId() { | |||
return id != NULL_ID; | |||
} | |||
/** | |||
* @return the group id | |||
* @throws IllegalStateException if {@link #getId()} is {@code false} | |||
*/ | |||
public long getId() { | |||
checkState(hasId(), "Id is not present. Please see hasId()."); | |||
return id; | |||
} | |||
/** | |||
* @return the organization key | |||
* @throws IllegalStateException if {@link #getId()} is {@code true} | |||
*/ | |||
@CheckForNull | |||
public String getOrganizationKey() { | |||
checkState(!hasId(), "Organization is not present. Please see hasId()."); | |||
return organizationKey; | |||
} | |||
/** | |||
* @return the non-null group name. Can be anyone. | |||
* @throws IllegalStateException if {@link #getId()} is {@code true} | |||
*/ | |||
public String getName() { | |||
checkState(!hasId(), "Name is not present. Please see hasId()."); | |||
return name; | |||
} | |||
/** | |||
* Creates a reference to a group by its id. Virtual groups "Anyone" can't be returned | |||
* as they can't be referenced by an id. | |||
*/ | |||
static GroupWsRef fromId(long id) { | |||
checkArgument(id > -1, "Group id must be positive: %s", id); | |||
return new GroupWsRef(id, null, null); | |||
} | |||
/** | |||
* Creates a reference to a group by its organization and name. Virtual groups "Anyone" are | |||
* supported. | |||
* | |||
* @param organizationKey key of organization. If {@code null}, then default organization will be used. | |||
* @param name non-null name. Can refer to anyone group (case-insensitive {@code "anyone"}). | |||
*/ | |||
static GroupWsRef fromName(@Nullable String organizationKey, String name) { | |||
return new GroupWsRef(NULL_ID, organizationKey, requireNonNull(name)); | |||
} | |||
public static GroupWsRef create(@Nullable Long id, @Nullable String organizationKey, @Nullable String name) { | |||
if (id != null) { | |||
checkRequest(organizationKey == null && name == null, "Either group id or couple organization/group name must be set"); | |||
return fromId(id); | |||
} | |||
checkRequest(name != null, "Group name or group id must be provided"); | |||
return fromName(organizationKey, name); | |||
} | |||
public boolean isAnyone() { | |||
return !hasId() && DefaultGroups.isAnyone(name); | |||
} | |||
@Override | |||
public boolean equals(Object o) { | |||
if (this == o) { | |||
return true; | |||
} | |||
if (o == null || getClass() != o.getClass()) { | |||
return false; | |||
} | |||
GroupWsRef groupRef = (GroupWsRef) o; | |||
if (id != groupRef.id) { | |||
return false; | |||
} | |||
if (organizationKey != null ? !organizationKey.equals(groupRef.organizationKey) : (groupRef.organizationKey != null)) { | |||
return false; | |||
} | |||
return name != null ? name.equals(groupRef.name) : (groupRef.name == null); | |||
} | |||
@Override | |||
public int hashCode() { | |||
int result = (int) (id ^ (id >>> 32)); | |||
result = 31 * result + (organizationKey != null ? organizationKey.hashCode() : 0); | |||
result = 31 * result + (name != null ? name.hashCode() : 0); | |||
return result; | |||
} | |||
@Override | |||
public String toString() { | |||
StringBuilder sb = new StringBuilder("GroupWsRef{"); | |||
sb.append("id=").append(id); | |||
sb.append(", organizationKey='").append(organizationKey).append('\''); | |||
sb.append(", name='").append(name).append('\''); | |||
sb.append('}'); | |||
return sb.toString(); | |||
} | |||
} |
@@ -0,0 +1,195 @@ | |||
/* | |||
* 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 org.sonar.server.usergroups.ws; | |||
import java.util.Optional; | |||
import javax.annotation.CheckForNull; | |||
import javax.annotation.Nullable; | |||
import org.sonar.api.server.ws.Request; | |||
import org.sonar.api.server.ws.WebService; | |||
import org.sonar.api.user.UserGroupValidation; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.organization.OrganizationDto; | |||
import org.sonar.db.user.GroupDto; | |||
import org.sonar.server.exceptions.BadRequestException; | |||
import org.sonar.server.exceptions.NotFoundException; | |||
import org.sonar.server.organization.DefaultOrganizationProvider; | |||
import org.sonarqube.ws.WsUserGroups; | |||
import static com.google.common.base.Preconditions.checkArgument; | |||
import static java.lang.String.format; | |||
import static org.sonar.server.ws.WsUtils.checkFound; | |||
import static org.sonar.server.ws.WsUtils.checkFoundWithOptional; | |||
/** | |||
* Factorizes code about user groups between web services | |||
*/ | |||
public class GroupWsSupport { | |||
static final String PARAM_GROUP_ID = "id"; | |||
static final String PARAM_ORGANIZATION_KEY = "organization"; | |||
static final String PARAM_GROUP_NAME = "name"; | |||
static final String PARAM_GROUP_DESCRIPTION = "description"; | |||
static final String PARAM_LOGIN = "login"; | |||
// Database column size should be 500 (since migration #353), | |||
// but on some instances, column size is still 200, | |||
// hence the validation is done with 200 | |||
static final int DESCRIPTION_MAX_LENGTH = 200; | |||
private final DbClient dbClient; | |||
private final DefaultOrganizationProvider defaultOrganizationProvider; | |||
public GroupWsSupport(DbClient dbClient, DefaultOrganizationProvider defaultOrganizationProvider) { | |||
this.dbClient = dbClient; | |||
this.defaultOrganizationProvider = defaultOrganizationProvider; | |||
} | |||
/** | |||
* Find a group by its id (parameter {@link #PARAM_GROUP_ID}) or couple organization key/group name | |||
* (parameters {@link #PARAM_ORGANIZATION_KEY} and {@link #PARAM_GROUP_NAME}). The virtual | |||
* group "Anyone" is not supported. | |||
* | |||
* @throws NotFoundException if parameters are missing/incorrect, if the requested group does not exist | |||
* or if the virtual group "Anyone" is requested. | |||
*/ | |||
public GroupId findGroup(DbSession dbSession, Request request) { | |||
Long id = request.paramAsLong(PARAM_GROUP_ID); | |||
String organizationKey = request.param(PARAM_ORGANIZATION_KEY); | |||
String name = request.param(PARAM_GROUP_NAME); | |||
return findGroup(dbSession, GroupWsRef.create(id, organizationKey, name)); | |||
} | |||
/** | |||
* Finds a user group by its reference. If organization is not defined then group | |||
* is searched in default organization. | |||
* | |||
* @return non-null group | |||
* @throws NotFoundException if the requested group does not exist | |||
* @throws NotFoundException if the requested group is Anyone | |||
*/ | |||
public GroupId findGroup(DbSession dbSession, GroupWsRef ref) { | |||
if (ref.hasId()) { | |||
GroupDto group = dbClient.groupDao().selectById(dbSession, ref.getId()); | |||
checkFound(group, "No group with id '%s'", ref.getId()); | |||
return GroupId.from(group); | |||
} | |||
OrganizationDto org = findOrganizationByKey(dbSession, ref.getOrganizationKey()); | |||
Optional<GroupDto> group = dbClient.groupDao().selectByName(dbSession, org.getUuid(), ref.getName()); | |||
checkFoundWithOptional(group, "No group with name '%s' in organization '%s'", ref.getName(), org.getKey()); | |||
return GroupId.from(group.get()); | |||
} | |||
public GroupIdOrAnyone findGroupOrAnyone(DbSession dbSession, GroupWsRef ref) { | |||
if (ref.hasId()) { | |||
GroupDto group = dbClient.groupDao().selectById(dbSession, ref.getId()); | |||
checkFound(group, "No group with id '%s'", ref.getId()); | |||
return GroupIdOrAnyone.from(group); | |||
} | |||
OrganizationDto org = findOrganizationByKey(dbSession, ref.getOrganizationKey()); | |||
if (ref.isAnyone()) { | |||
return GroupIdOrAnyone.forAnyone(org.getUuid()); | |||
} | |||
Optional<GroupDto> group = dbClient.groupDao().selectByName(dbSession, org.getUuid(), ref.getName()); | |||
checkFoundWithOptional(group, "No group with name '%s' in organization '%s'", ref.getName(), org.getKey()); | |||
return GroupIdOrAnyone.from(group.get()); | |||
} | |||
/** | |||
* Loads organization from database by its key. | |||
* @param dbSession | |||
* @param key the organization key, or {@code null} to get the default organization | |||
* @return non-null organization | |||
* @throws NotFoundException if no organizations match the provided key | |||
*/ | |||
public OrganizationDto findOrganizationByKey(DbSession dbSession, @Nullable String key) { | |||
String effectiveKey = key; | |||
if (effectiveKey == null) { | |||
effectiveKey = defaultOrganizationProvider.get().getKey(); | |||
} | |||
Optional<OrganizationDto> org = dbClient.organizationDao().selectByKey(dbSession, effectiveKey); | |||
checkFoundWithOptional(org, "No organization with key '%s'", key); | |||
return org.get(); | |||
} | |||
/** | |||
* Similar to {@link UserGroupValidation#validateGroupName(String)} but kept internal. No need to publish | |||
* this method in public API. | |||
* @return the same description | |||
*/ | |||
@CheckForNull | |||
String validateDescription(@Nullable String description) { | |||
checkArgument(description == null || description.length() <= DESCRIPTION_MAX_LENGTH, | |||
"Description cannot be longer than %s characters", DESCRIPTION_MAX_LENGTH); | |||
return description; | |||
} | |||
void checkNameDoesNotExist(DbSession dbSession, String organizationUuid, String name) { | |||
// 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().selectByName(dbSession, organizationUuid, name).isPresent()) { | |||
throw new BadRequestException(format("Group '%s' already exists", name)); | |||
} | |||
} | |||
static WsUserGroups.Group.Builder toProtobuf(OrganizationDto organization, GroupDto group, int membersCount) { | |||
WsUserGroups.Group.Builder wsGroup = WsUserGroups.Group.newBuilder() | |||
.setId(group.getId()) | |||
.setOrganization(organization.getKey()) | |||
.setName(group.getName()) | |||
.setMembersCount(membersCount); | |||
if (group.getDescription() != null) { | |||
wsGroup.setDescription(group.getDescription()); | |||
} | |||
return wsGroup; | |||
} | |||
static void defineGroupWsParameters(WebService.NewAction action) { | |||
defineGroupIdWsParameter(action); | |||
defineGroupNameWsParameter(action); | |||
} | |||
private static void defineGroupIdWsParameter(WebService.NewAction action) { | |||
action.createParam(PARAM_GROUP_ID) | |||
.setDescription("Group id") | |||
.setExampleValue("42"); | |||
} | |||
private static void defineGroupNameWsParameter(WebService.NewAction action) { | |||
action.createParam(PARAM_ORGANIZATION_KEY) | |||
.setDescription("Key of organization") | |||
.setExampleValue("my-org") | |||
.setSince("6.2"); | |||
action.createParam(PARAM_GROUP_NAME) | |||
.setDescription("Group name") | |||
.setExampleValue("sonar-administrators"); | |||
} | |||
static WebService.NewParam defineLoginWsParameter(WebService.NewAction action) { | |||
return action.createParam(PARAM_LOGIN) | |||
.setDescription("User login") | |||
.setExampleValue("g.hopper"); | |||
} | |||
} |
@@ -19,8 +19,6 @@ | |||
*/ | |||
package org.sonar.server.usergroups.ws; | |||
import javax.annotation.CheckForNull; | |||
import org.sonar.api.security.DefaultGroups; | |||
import org.sonar.api.server.ws.Request; | |||
import org.sonar.api.server.ws.Response; | |||
import org.sonar.api.server.ws.WebService.NewAction; | |||
@@ -28,29 +26,27 @@ import org.sonar.api.server.ws.WebService.NewController; | |||
import org.sonar.core.permission.GlobalPermissions; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.user.GroupDto; | |||
import org.sonar.db.user.UserDto; | |||
import org.sonar.db.user.UserGroupDto; | |||
import org.sonar.server.user.UserSession; | |||
import static java.lang.String.format; | |||
import static org.sonar.api.security.DefaultGroups.isAnyone; | |||
import static org.sonar.server.usergroups.ws.UserGroupsWsParameters.PARAM_GROUP_ID; | |||
import static org.sonar.server.usergroups.ws.UserGroupsWsParameters.PARAM_GROUP_NAME; | |||
import static org.sonar.server.usergroups.ws.UserGroupsWsParameters.PARAM_LOGIN; | |||
import static org.sonar.server.usergroups.ws.UserGroupsWsParameters.createGroupParameters; | |||
import static org.sonar.server.usergroups.ws.UserGroupsWsParameters.createLoginParameter; | |||
import static org.sonar.server.usergroups.ws.GroupWsSupport.PARAM_GROUP_ID; | |||
import static org.sonar.server.usergroups.ws.GroupWsSupport.PARAM_GROUP_NAME; | |||
import static org.sonar.server.usergroups.ws.GroupWsSupport.PARAM_LOGIN; | |||
import static org.sonar.server.usergroups.ws.GroupWsSupport.defineGroupWsParameters; | |||
import static org.sonar.server.usergroups.ws.GroupWsSupport.defineLoginWsParameter; | |||
import static org.sonar.server.ws.WsUtils.checkFound; | |||
import static org.sonar.server.ws.WsUtils.checkRequest; | |||
public class RemoveUserAction implements UserGroupsWsAction { | |||
private final DbClient dbClient; | |||
private final UserSession userSession; | |||
private final GroupWsSupport support; | |||
public RemoveUserAction(DbClient dbClient, UserSession userSession) { | |||
public RemoveUserAction(DbClient dbClient, UserSession userSession, GroupWsSupport support) { | |||
this.dbClient = dbClient; | |||
this.userSession = userSession; | |||
this.support = support; | |||
} | |||
@Override | |||
@@ -62,59 +58,25 @@ public class RemoveUserAction implements UserGroupsWsAction { | |||
.setPost(true) | |||
.setSince("5.2"); | |||
createGroupParameters(action); | |||
createLoginParameter(action); | |||
defineGroupWsParameters(action); | |||
defineLoginWsParameter(action); | |||
} | |||
@Override | |||
public void handle(Request request, Response response) throws Exception { | |||
userSession.checkLoggedIn().checkPermission(GlobalPermissions.SYSTEM_ADMIN); | |||
WsGroupRef wsGroupRef = WsGroupRef.newWsGroupRefFromUserGroupRequest(request); | |||
String login = request.mandatoryParam(PARAM_LOGIN); | |||
try (DbSession dbSession = dbClient.openSession(false)) { | |||
GroupId group = support.findGroup(dbSession, request); | |||
DbSession dbSession = dbClient.openSession(false); | |||
try { | |||
GroupDto group = getGroup(dbSession, wsGroupRef); | |||
checkRequest(group != null, "It is not possible to remove a user from the '%s' group.", DefaultGroups.ANYONE); | |||
String login = request.mandatoryParam(PARAM_LOGIN); | |||
UserDto user = getUser(dbSession, login); | |||
UserGroupDto userGroup = new UserGroupDto().setGroupId(group.getId()).setUserId(user.getId()); | |||
dbClient.userGroupDao().delete(dbSession, userGroup); | |||
dbClient.userGroupDao().delete(dbSession, group.getId(), user.getId()); | |||
dbSession.commit(); | |||
response.noContent(); | |||
} finally { | |||
dbClient.closeSession(dbSession); | |||
} | |||
} | |||
/** | |||
* | |||
* @return null if it's the anyone group | |||
*/ | |||
@CheckForNull | |||
private GroupDto getGroup(DbSession dbSession, WsGroupRef group) { | |||
Long groupId = group.id(); | |||
String groupName = group.name(); | |||
if (isAnyone(groupName)) { | |||
return null; | |||
} | |||
GroupDto groupDto = null; | |||
if (groupId != null) { | |||
groupDto = checkFound(dbClient.groupDao().selectById(dbSession, groupId), | |||
"Group with id '%d' is not found", groupId); | |||
} | |||
if (groupName != null) { | |||
groupDto = checkFound(dbClient.groupDao().selectByName(dbSession, groupName), | |||
"Group with name '%s' is not found", groupName); | |||
response.noContent(); | |||
} | |||
return groupDto; | |||
} | |||
private UserDto getUser(DbSession dbSession, String userLogin) { |
@@ -19,28 +19,28 @@ | |||
*/ | |||
package org.sonar.server.usergroups.ws; | |||
import com.google.common.base.Function; | |||
import com.google.common.collect.Collections2; | |||
import com.google.common.collect.Sets; | |||
import java.util.Arrays; | |||
import java.util.Collection; | |||
import java.util.List; | |||
import java.util.Map; | |||
import java.util.Set; | |||
import javax.annotation.Nonnull; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.sonar.api.server.ws.Request; | |||
import org.sonar.api.server.ws.Response; | |||
import org.sonar.api.server.ws.WebService; | |||
import org.sonar.api.server.ws.WebService.NewController; | |||
import org.sonar.api.server.ws.WebService.Param; | |||
import org.sonar.api.utils.text.JsonWriter; | |||
import org.sonar.core.util.stream.Collectors; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.organization.OrganizationDto; | |||
import org.sonar.db.user.GroupDto; | |||
import org.sonar.server.es.SearchOptions; | |||
import org.sonar.server.user.UserSession; | |||
import static org.apache.commons.lang.StringUtils.defaultIfBlank; | |||
import static org.sonar.server.es.SearchOptions.MAX_LIMIT; | |||
import static org.sonar.server.usergroups.ws.GroupWsSupport.PARAM_ORGANIZATION_KEY; | |||
public class SearchAction implements UserGroupsWsAction { | |||
@@ -52,15 +52,17 @@ public class SearchAction implements UserGroupsWsAction { | |||
private final DbClient dbClient; | |||
private final UserSession userSession; | |||
private final GroupWsSupport groupWsSupport; | |||
public SearchAction(DbClient dbClient, UserSession userSession) { | |||
public SearchAction(DbClient dbClient, UserSession userSession, GroupWsSupport groupWsSupport) { | |||
this.dbClient = dbClient; | |||
this.userSession = userSession; | |||
this.groupWsSupport = groupWsSupport; | |||
} | |||
@Override | |||
public void define(NewController context) { | |||
context.createAction("search") | |||
WebService.NewAction action = context.createAction("search") | |||
.setDescription("Search for user groups.<br>" + | |||
"Requires to be logged.") | |||
.setHandler(this) | |||
@@ -69,37 +71,37 @@ public class SearchAction implements UserGroupsWsAction { | |||
.addFieldsParam(ALL_FIELDS) | |||
.addPagingParams(100, MAX_LIMIT) | |||
.addSearchQuery("sonar-users", "names"); | |||
action.createParam(PARAM_ORGANIZATION_KEY) | |||
.setDescription("Key of organization. If not set then groups are searched in default organization.") | |||
.setExampleValue("my-org") | |||
.setSince("6.2"); | |||
} | |||
@Override | |||
public void handle(Request request, Response response) throws Exception { | |||
userSession.checkLoggedIn(); | |||
int page = request.mandatoryParamAsInt(Param.PAGE); | |||
int pageSize = request.mandatoryParamAsInt(Param.PAGE_SIZE); | |||
SearchOptions options = new SearchOptions() | |||
.setPage(page, pageSize); | |||
String query = StringUtils.defaultIfBlank(request.param(Param.TEXT_QUERY), ""); | |||
String query = defaultIfBlank(request.param(Param.TEXT_QUERY), ""); | |||
Set<String> fields = neededFields(request); | |||
DbSession dbSession = dbClient.openSession(false); | |||
try { | |||
int limit = dbClient.groupDao().countByQuery(dbSession, query); | |||
List<GroupDto> groups = dbClient.groupDao().selectByQuery(dbSession, query, options.getOffset(), pageSize); | |||
Collection<Long> groupIds = Collections2.transform(groups, new Function<GroupDto, Long>() { | |||
@Override | |||
public Long apply(@Nonnull GroupDto input) { | |||
return input.getId(); | |||
} | |||
}); | |||
try (DbSession dbSession = dbClient.openSession(false)) { | |||
OrganizationDto organization = groupWsSupport.findOrganizationByKey(dbSession, request.param(PARAM_ORGANIZATION_KEY)); | |||
int limit = dbClient.groupDao().countByQuery(dbSession, organization.getUuid(), query); | |||
List<GroupDto> groups = dbClient.groupDao().selectByQuery(dbSession, organization.getUuid(), query, options.getOffset(), pageSize); | |||
List<Long> groupIds = groups.stream().map(GroupDto::getId).collect(Collectors.toList(groups.size())); | |||
Map<String, Integer> userCountByGroup = dbClient.groupMembershipDao().countUsersByGroups(dbSession, groupIds); | |||
JsonWriter json = response.newJsonWriter().beginObject(); | |||
options.writeJson(json, limit); | |||
writeGroups(json, groups, userCountByGroup, fields); | |||
json.endObject().close(); | |||
} finally { | |||
dbClient.closeSession(dbSession); | |||
} | |||
} | |||
@@ -20,40 +20,50 @@ | |||
package org.sonar.server.usergroups.ws; | |||
import java.util.Objects; | |||
import java.util.Optional; | |||
import org.sonar.api.server.ws.Request; | |||
import org.sonar.api.server.ws.Response; | |||
import org.sonar.api.server.ws.WebService.NewAction; | |||
import org.sonar.api.server.ws.WebService.NewController; | |||
import org.sonar.api.utils.text.JsonWriter; | |||
import org.sonar.api.user.UserGroupValidation; | |||
import org.sonar.core.permission.GlobalPermissions; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.organization.OrganizationDto; | |||
import org.sonar.db.user.GroupDto; | |||
import org.sonar.server.exceptions.NotFoundException; | |||
import org.sonar.db.user.GroupMembershipQuery; | |||
import org.sonar.db.user.UserMembershipQuery; | |||
import org.sonar.server.organization.DefaultOrganizationProvider; | |||
import org.sonar.server.platform.PersistentSettings; | |||
import org.sonar.server.user.UserSession; | |||
import org.sonarqube.ws.WsUserGroups; | |||
import static java.util.Collections.singletonList; | |||
import static org.sonar.api.CoreProperties.CORE_DEFAULT_GROUP; | |||
import static org.sonar.api.user.UserGroupValidation.GROUP_NAME_MAX_LENGTH; | |||
import static org.sonar.db.MyBatis.closeQuietly; | |||
import static org.sonar.server.usergroups.ws.UserGroupUpdater.DESCRIPTION_MAX_LENGTH; | |||
import static org.sonar.server.usergroups.ws.UserGroupUpdater.PARAM_DESCRIPTION; | |||
import static org.sonar.server.usergroups.ws.UserGroupUpdater.PARAM_ID; | |||
import static org.sonar.server.usergroups.ws.UserGroupUpdater.PARAM_NAME; | |||
import static org.sonar.server.usergroups.ws.GroupWsSupport.DESCRIPTION_MAX_LENGTH; | |||
import static org.sonar.server.usergroups.ws.GroupWsSupport.PARAM_GROUP_DESCRIPTION; | |||
import static org.sonar.server.usergroups.ws.GroupWsSupport.PARAM_GROUP_ID; | |||
import static org.sonar.server.usergroups.ws.GroupWsSupport.PARAM_GROUP_NAME; | |||
import static org.sonar.server.usergroups.ws.GroupWsSupport.toProtobuf; | |||
import static org.sonar.server.ws.WsUtils.checkFound; | |||
import static org.sonar.server.ws.WsUtils.checkFoundWithOptional; | |||
import static org.sonar.server.ws.WsUtils.writeProtobuf; | |||
public class UpdateAction implements UserGroupsWsAction { | |||
private final DbClient dbClient; | |||
private final UserSession userSession; | |||
private final GroupWsSupport support; | |||
private final PersistentSettings persistentSettings; | |||
private final UserGroupUpdater groupUpdater; | |||
private final DefaultOrganizationProvider defaultOrganizationProvider; | |||
public UpdateAction(DbClient dbClient, UserSession userSession, UserGroupUpdater groupUpdater, PersistentSettings persistentSettings) { | |||
public UpdateAction(DbClient dbClient, UserSession userSession, GroupWsSupport support, PersistentSettings persistentSettings, | |||
DefaultOrganizationProvider defaultOrganizationProvider) { | |||
this.dbClient = dbClient; | |||
this.groupUpdater = groupUpdater; | |||
this.userSession = userSession; | |||
this.support = support; | |||
this.persistentSettings = persistentSettings; | |||
this.defaultOrganizationProvider = defaultOrganizationProvider; | |||
} | |||
@Override | |||
@@ -65,18 +75,19 @@ public class UpdateAction implements UserGroupsWsAction { | |||
.setResponseExample(getClass().getResource("example-update.json")) | |||
.setSince("5.2"); | |||
action.createParam(PARAM_ID) | |||
action.createParam(PARAM_GROUP_ID) | |||
.setDescription("Identifier of the group.") | |||
.setExampleValue("42") | |||
.setRequired(true); | |||
action.createParam(PARAM_NAME) | |||
.setDescription(String.format("New name for the group. A group name cannot be larger than %d characters and must be unique. " + | |||
"The value 'anyone' (whatever the case) is reserved and cannot be used.", GROUP_NAME_MAX_LENGTH)) | |||
action.createParam(PARAM_GROUP_NAME) | |||
.setDescription(String.format("New optional name for the group. A group name cannot be larger than %d characters and must be unique. " + | |||
"The value 'anyone' (whatever the case) is reserved and cannot be used. If value is empty or not defined, then name is not changed.", GROUP_NAME_MAX_LENGTH)) | |||
.setExampleValue("sonar-users"); | |||
action.createParam(PARAM_DESCRIPTION) | |||
.setDescription(String.format("New description for the group. A group description cannot be larger than %d characters.", DESCRIPTION_MAX_LENGTH)) | |||
action.createParam(PARAM_GROUP_DESCRIPTION) | |||
.setDescription(String.format("New optional description for the group. A group description cannot be larger than %d characters. " + | |||
"If value is not defined, then description is not changed.", DESCRIPTION_MAX_LENGTH)) | |||
.setExampleValue("Default group for new users"); | |||
} | |||
@@ -84,42 +95,60 @@ public class UpdateAction implements UserGroupsWsAction { | |||
public void handle(Request request, Response response) throws Exception { | |||
userSession.checkLoggedIn().checkPermission(GlobalPermissions.SYSTEM_ADMIN); | |||
Long groupId = request.mandatoryParamAsLong(PARAM_ID); | |||
String name = request.param(PARAM_NAME); | |||
String description = request.param(PARAM_DESCRIPTION); | |||
DbSession dbSession = dbClient.openSession(false); | |||
try { | |||
try (DbSession dbSession = dbClient.openSession(false)) { | |||
long groupId = request.mandatoryParamAsLong(PARAM_GROUP_ID); | |||
GroupDto group = dbClient.groupDao().selectById(dbSession, groupId); | |||
if (group == null) { | |||
throw new NotFoundException(String.format("Could not find a user group with id '%s'.", groupId)); | |||
} | |||
String oldName = group.getName(); | |||
if (name != null) { | |||
groupUpdater.checkNameIsUnique(name, dbSession); | |||
groupUpdater.validateName(name); | |||
group.setName(name); | |||
updateDefaultGroupIfNeeded(dbSession, oldName, name); | |||
checkFound(group, "Could not find a user group with id '%s'.", groupId); | |||
Optional<OrganizationDto> org = dbClient.organizationDao().selectByUuid(dbSession, group.getOrganizationUuid()); | |||
checkFoundWithOptional(org, "Could not find organization with id '%s'.", group.getOrganizationUuid()); | |||
boolean changed = false; | |||
String newName = request.param(PARAM_GROUP_NAME); | |||
if (newName != null) { | |||
changed = true; | |||
UserGroupValidation.validateGroupName(newName); | |||
support.checkNameDoesNotExist(dbSession, group.getOrganizationUuid(), newName); | |||
String oldName = group.getName(); | |||
group.setName(newName); | |||
updateDefaultGroupIfNeeded(dbSession, org.get(), oldName, newName); | |||
} | |||
String description = request.param(PARAM_GROUP_DESCRIPTION); | |||
if (description != null) { | |||
groupUpdater.validateDescription(description); | |||
group.setDescription(description); | |||
changed = true; | |||
group.setDescription(support.validateDescription(description)); | |||
} | |||
if (changed) { | |||
dbClient.groupDao().update(dbSession, group); | |||
dbSession.commit(); | |||
} | |||
dbClient.groupDao().update(dbSession, group); | |||
dbSession.commit(); | |||
JsonWriter json = response.newJsonWriter().beginObject(); | |||
groupUpdater.writeGroup(json, group, dbClient.groupMembershipDao().countUsersByGroups(dbSession, singletonList(groupId)).get(group.getName())); | |||
json.endObject().close(); | |||
} finally { | |||
closeQuietly(dbSession); | |||
writeResponse(dbSession, request, response, org.get(), group); | |||
} | |||
} | |||
private void updateDefaultGroupIfNeeded(DbSession dbSession, String oldName, String newName) { | |||
String defaultGroupName = persistentSettings.getString(CORE_DEFAULT_GROUP); | |||
if (Objects.equals(defaultGroupName, oldName)) { | |||
persistentSettings.saveProperty(dbSession, CORE_DEFAULT_GROUP, newName); | |||
private void updateDefaultGroupIfNeeded(DbSession dbSession, OrganizationDto org, String oldName, String newName) { | |||
// The feature "default group" relies on a property. As organization properties are | |||
// not implemented yet, default groups are not supported on non-default organizations | |||
if (defaultOrganizationProvider.get().getUuid().equals(org.getUuid())) { | |||
String defaultGroupName = persistentSettings.getString(CORE_DEFAULT_GROUP); | |||
if (Objects.equals(defaultGroupName, oldName)) { | |||
persistentSettings.saveProperty(dbSession, CORE_DEFAULT_GROUP, newName); | |||
} | |||
} | |||
} | |||
private void writeResponse(DbSession dbSession, Request request, Response response, OrganizationDto organization, GroupDto group) { | |||
UserMembershipQuery query = UserMembershipQuery.builder() | |||
.groupId(group.getId()) | |||
.membership(GroupMembershipQuery.IN) | |||
.build(); | |||
int membersCount = dbClient.groupMembershipDao().countMembers(dbSession, query); | |||
WsUserGroups.UpdateResponse.Builder respBuilder = WsUserGroups.UpdateResponse.newBuilder(); | |||
respBuilder.setGroup(toProtobuf(organization, group, membersCount)); | |||
writeProtobuf(respBuilder.build(), request, response); | |||
} | |||
} |
@@ -1,74 +0,0 @@ | |||
/* | |||
* 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 org.sonar.server.usergroups.ws; | |||
import com.google.common.base.Preconditions; | |||
import org.sonar.api.server.ServerSide; | |||
import org.sonar.api.user.UserGroupValidation; | |||
import org.sonar.api.utils.text.JsonWriter; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.user.GroupDto; | |||
import org.sonar.server.exceptions.BadRequestException; | |||
@ServerSide | |||
public class UserGroupUpdater { | |||
static final String PARAM_ID = "id"; | |||
static final String PARAM_DESCRIPTION = "description"; | |||
static final String PARAM_NAME = "name"; | |||
// Database column size should be 500 (since migration #353), | |||
// but on some instances, column size is still 255, | |||
// hence the validation is done with 255 | |||
static final int DESCRIPTION_MAX_LENGTH = 200; | |||
private final DbClient dbClient; | |||
public UserGroupUpdater(DbClient dbClient) { | |||
this.dbClient = dbClient; | |||
} | |||
protected void validateName(String name) { | |||
UserGroupValidation.validateGroupName(name); | |||
} | |||
protected 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().selectByName(session, name) != null) { | |||
throw new BadRequestException(String.format("Name '%s' is already taken", name)); | |||
} | |||
} | |||
protected void validateDescription(String description) { | |||
Preconditions.checkArgument(description.length() <= DESCRIPTION_MAX_LENGTH, String.format("Description cannot be longer than %d characters", DESCRIPTION_MAX_LENGTH)); | |||
} | |||
protected void writeGroup(JsonWriter json, GroupDto group, int membersCount) { | |||
json.name("group").beginObject() | |||
.prop(PARAM_ID, group.getId().toString()) | |||
.prop(PARAM_NAME, group.getName()) | |||
.prop(PARAM_DESCRIPTION, group.getDescription()) | |||
.prop("membersCount", membersCount) | |||
.endObject(); | |||
} | |||
} |
@@ -27,8 +27,7 @@ public class UserGroupsModule extends Module { | |||
protected void configureModule() { | |||
add( | |||
UserGroupsWs.class, | |||
UserGroupUpdater.class, | |||
UserGroupFinder.class, | |||
GroupWsSupport.class, | |||
// actions | |||
SearchAction.class, | |||
CreateAction.class, |
@@ -1,56 +0,0 @@ | |||
/* | |||
* 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 org.sonar.server.usergroups.ws; | |||
import org.sonar.api.server.ws.WebService.NewAction; | |||
import org.sonar.api.server.ws.WebService.NewParam; | |||
public class UserGroupsWsParameters { | |||
static final String PARAM_GROUP_NAME = "name"; | |||
static final String PARAM_GROUP_ID = "id"; | |||
static final String PARAM_LOGIN = "login"; | |||
private UserGroupsWsParameters() { | |||
// static methods only | |||
} | |||
static void createGroupParameters(NewAction action) { | |||
createGroupIdParameter(action); | |||
createGroupNameParameter(action); | |||
} | |||
private static void createGroupIdParameter(NewAction action) { | |||
action.createParam(PARAM_GROUP_ID) | |||
.setDescription("Group id") | |||
.setExampleValue("42"); | |||
} | |||
private static void createGroupNameParameter(NewAction action) { | |||
action.createParam(PARAM_GROUP_NAME) | |||
.setDescription("Group name") | |||
.setExampleValue("sonar-administrators"); | |||
} | |||
static NewParam createLoginParameter(NewAction action) { | |||
return action.createParam(PARAM_LOGIN) | |||
.setDescription("User login") | |||
.setExampleValue("g.hopper"); | |||
} | |||
} |
@@ -31,15 +31,13 @@ import org.sonar.api.utils.text.JsonWriter; | |||
import org.sonar.core.permission.GlobalPermissions; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.MyBatis; | |||
import org.sonar.db.user.GroupDto; | |||
import org.sonar.db.user.GroupMembershipQuery; | |||
import org.sonar.db.user.UserMembershipDto; | |||
import org.sonar.db.user.UserMembershipQuery; | |||
import org.sonar.server.user.UserSession; | |||
import static org.sonar.api.utils.Paging.forPageIndex; | |||
import static org.sonar.server.usergroups.ws.UserGroupsWsParameters.createGroupParameters; | |||
import static org.sonar.server.usergroups.ws.GroupWsSupport.defineGroupWsParameters; | |||
public class UsersAction implements UserGroupsWsAction { | |||
@@ -48,13 +46,13 @@ public class UsersAction implements UserGroupsWsAction { | |||
private static final String FIELD_LOGIN = "login"; | |||
private final DbClient dbClient; | |||
private final UserGroupFinder userGroupFinder; | |||
private final UserSession userSession; | |||
private final GroupWsSupport support; | |||
public UsersAction(DbClient dbClient, UserGroupFinder userGroupFinder, UserSession userSession) { | |||
public UsersAction(DbClient dbClient, UserSession userSession, GroupWsSupport support) { | |||
this.dbClient = dbClient; | |||
this.userGroupFinder = userGroupFinder; | |||
this.userSession = userSession; | |||
this.support = support; | |||
} | |||
@Override | |||
@@ -68,26 +66,23 @@ public class UsersAction implements UserGroupsWsAction { | |||
.addSearchQuery("freddy", "names", "logins") | |||
.addPagingParams(25); | |||
createGroupParameters(action); | |||
defineGroupWsParameters(action); | |||
} | |||
@Override | |||
public void handle(Request request, Response response) throws Exception { | |||
userSession.checkLoggedIn().checkPermission(GlobalPermissions.SYSTEM_ADMIN); | |||
WsGroupRef wsGroupRef = WsGroupRef.newWsGroupRefFromUserGroupRequest(request); | |||
int pageSize = request.mandatoryParamAsInt(Param.PAGE_SIZE); | |||
int page = request.mandatoryParamAsInt(Param.PAGE); | |||
String queryString = request.param(Param.TEXT_QUERY); | |||
String selected = request.mandatoryParam(Param.SELECTED); | |||
DbSession dbSession = dbClient.openSession(false); | |||
try { | |||
GroupDto group = userGroupFinder.getGroup(dbSession, wsGroupRef); | |||
long groupId = group.getId(); | |||
try (DbSession dbSession = dbClient.openSession(false)) { | |||
GroupId group = support.findGroup(dbSession, request); | |||
UserMembershipQuery query = UserMembershipQuery.builder() | |||
.groupId(groupId) | |||
.groupId(group.getId()) | |||
.memberSearch(queryString) | |||
.membership(getMembership(selected)) | |||
.pageIndex(page) | |||
@@ -101,8 +96,6 @@ public class UsersAction implements UserGroupsWsAction { | |||
writeMembers(json, users); | |||
writePaging(json, paging); | |||
json.endObject().close(); | |||
} finally { | |||
MyBatis.closeQuietly(dbSession); | |||
} | |||
} | |||
@@ -124,7 +117,7 @@ public class UsersAction implements UserGroupsWsAction { | |||
.prop("total", paging.total()); | |||
} | |||
private String getMembership(String selected) { | |||
private static String getMembership(String selected) { | |||
SelectionMode selectionMode = SelectionMode.fromParam(selected); | |||
String membership = GroupMembershipQuery.ANY; | |||
if (SelectionMode.SELECTED == selectionMode) { |
@@ -1,63 +0,0 @@ | |||
/* | |||
* 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 org.sonar.server.usergroups.ws; | |||
import javax.annotation.CheckForNull; | |||
import javax.annotation.Nullable; | |||
import org.sonar.api.server.ws.Request; | |||
import static org.sonar.server.ws.WsUtils.checkRequest; | |||
/** | |||
* Group from a WS request. Guaranties the group id or the group name is provided, not both. | |||
*/ | |||
public class WsGroupRef { | |||
private final Long id; | |||
private final String name; | |||
private WsGroupRef(@Nullable Long id, @Nullable String name) { | |||
checkRequest(id != null ^ name != null, "Group name or group id must be provided, not both."); | |||
this.id = id; | |||
this.name = name; | |||
} | |||
public static WsGroupRef newWsGroupRef(@Nullable Long id, @Nullable String name) { | |||
return new WsGroupRef(id, name); | |||
} | |||
public static WsGroupRef newWsGroupRefFromUserGroupRequest(Request wsRequest) { | |||
Long id = wsRequest.paramAsLong(UserGroupsWsParameters.PARAM_GROUP_ID); | |||
String name = wsRequest.param(UserGroupsWsParameters.PARAM_GROUP_NAME); | |||
return new WsGroupRef(id, name); | |||
} | |||
@CheckForNull | |||
public Long id() { | |||
return this.id; | |||
} | |||
@CheckForNull | |||
public String name() { | |||
return this.name; | |||
} | |||
} |
@@ -21,4 +21,3 @@ | |||
package org.sonar.server.usergroups.ws; | |||
import javax.annotation.ParametersAreNonnullByDefault; | |||
@@ -1,6 +1,7 @@ | |||
{ | |||
"group": { | |||
"id": "42", | |||
"organization": "my-org", | |||
"name": "some-product-bu", | |||
"description": "Business Unit for Some Awesome Product", | |||
"membersCount": 0 |
@@ -30,11 +30,8 @@ import org.sonar.core.permission.GlobalPermissions; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.DbTester; | |||
import org.sonar.db.component.ComponentDbTester; | |||
import org.sonar.db.component.ComponentDto; | |||
import org.sonar.db.component.ComponentTesting; | |||
import org.sonar.db.permission.GroupPermissionDto; | |||
import org.sonar.db.permission.UserPermissionDto; | |||
import org.sonar.db.user.UserDto; | |||
import org.sonar.server.exceptions.ForbiddenException; | |||
@@ -60,22 +57,19 @@ public class ServerUserSessionTest { | |||
}}.setLogin("regular_user"); | |||
@Rule | |||
public DbTester dbTester = DbTester.create(System2.INSTANCE); | |||
public DbTester db = DbTester.create(System2.INSTANCE); | |||
@Rule | |||
public ExpectedException expectedException = ExpectedException.none(); | |||
private ComponentDbTester componentDbTester = new ComponentDbTester(dbTester); | |||
private DbClient dbClient = dbTester.getDbClient(); | |||
private DbSession dbSession = dbTester.getSession(); | |||
private DbClient dbClient = db.getDbClient(); | |||
private UserDto userDto = newUserDto().setLogin(LOGIN); | |||
private ComponentDto project; | |||
@Before | |||
public void setUp() throws Exception { | |||
project = componentDbTester.insertComponent(ComponentTesting.newProjectDto(PROJECT_UUID)); | |||
componentDbTester.insertComponent(ComponentTesting.newFileDto(project, null, FILE_UUID).setKey(FILE_KEY)); | |||
dbClient.userDao().insert(dbSession, userDto); | |||
dbSession.commit(); | |||
project = db.components().insertComponent(ComponentTesting.newProjectDto(PROJECT_UUID)); | |||
db.components().insertComponent(ComponentTesting.newFileDto(project, null, FILE_UUID).setKey(FILE_KEY)); | |||
db.users().insertUser(userDto); | |||
} | |||
@Test | |||
@@ -221,8 +215,8 @@ public class ServerUserSessionTest { | |||
@Test | |||
public void checkComponentPermission_throws_FE_when_user_has_not_permission_for_specified_key_in_db() { | |||
ComponentDto project2 = componentDbTester.insertComponent(ComponentTesting.newProjectDto()); | |||
ComponentDto file2 = componentDbTester.insertComponent(ComponentTesting.newFileDto(project2, null)); | |||
ComponentDto project2 = db.components().insertComponent(ComponentTesting.newProjectDto()); | |||
ComponentDto file2 = db.components().insertComponent(ComponentTesting.newFileDto(project2, null)); | |||
addProjectPermissions(project, UserRole.USER); | |||
UserSession session = newUserSession(userDto); | |||
@@ -243,8 +237,8 @@ public class ServerUserSessionTest { | |||
@Test | |||
public void checkComponentPermission_fails_with_FE_when_project_of_specified_uuid_can_not_be_found() { | |||
ComponentDto project2 = componentDbTester.insertComponent(ComponentTesting.newProjectDto()); | |||
ComponentDto file2 = componentDbTester.insertComponent(ComponentTesting.newFileDto(project2, null) | |||
ComponentDto project2 = db.components().insertComponent(ComponentTesting.newProjectDto()); | |||
ComponentDto file2 = db.components().insertComponent(ComponentTesting.newFileDto(project2, null) | |||
// Simulate file is linked to an invalid project | |||
.setProjectUuid("INVALID")); | |||
addProjectPermissions(project, UserRole.USER); | |||
@@ -307,7 +301,7 @@ public class ServerUserSessionTest { | |||
@Test | |||
public void has_global_permission_for_anonymous() throws Exception { | |||
addAnonymousPermissions(null, "profileadmin", "admin"); | |||
addAnyonePermissions(null, "profileadmin", "admin"); | |||
UserSession session = newAnonymousSession(); | |||
assertThat(session.getLogin()).isNull(); | |||
@@ -320,7 +314,7 @@ public class ServerUserSessionTest { | |||
@Test | |||
public void has_project_permission_for_anonymous() throws Exception { | |||
addAnonymousPermissions(project, UserRole.USER); | |||
addAnyonePermissions(project, UserRole.USER); | |||
UserSession session = newAnonymousSession(); | |||
assertThat(session.hasComponentPermission(UserRole.USER, FILE_KEY)).isTrue(); | |||
@@ -344,20 +338,24 @@ public class ServerUserSessionTest { | |||
addPermissions(component, permissions); | |||
} | |||
private void addPermissions( @Nullable ComponentDto component, String... permissions) { | |||
private void addPermissions(@Nullable ComponentDto component, String... permissions) { | |||
for (String permission : permissions) { | |||
dbClient.userPermissionDao().insert(dbSession, new UserPermissionDto(permission, userDto.getId(), component == null ? null : component.getId())); | |||
if (component == null) { | |||
db.users().insertPermissionOnUser(userDto, permission); | |||
} else { | |||
db.users().insertProjectPermissionOnUser(userDto, permission, component); | |||
} | |||
} | |||
dbSession.commit(); | |||
} | |||
private void addAnonymousPermissions(@Nullable ComponentDto component, String... permissions) { | |||
private void addAnyonePermissions(@Nullable ComponentDto component, String... permissions) { | |||
for (String permission : permissions) { | |||
dbClient.roleDao().insertGroupRole(dbSession, new GroupPermissionDto() | |||
.setRole(permission) | |||
.setResourceId(component == null ? null : component.getId())); | |||
if (component == null) { | |||
db.users().insertPermissionOnAnyone(permission); | |||
} else { | |||
db.users().insertProjectPermissionOnAnyone(permission, component); | |||
} | |||
} | |||
dbSession.commit(); | |||
} | |||
private void expectInsufficientPrivilegesForbiddenException() { | |||
@@ -365,5 +363,4 @@ public class ServerUserSessionTest { | |||
expectedException.expectMessage("Insufficient privileges"); | |||
} | |||
} |
@@ -19,164 +19,153 @@ | |||
*/ | |||
package org.sonar.server.usergroups.ws; | |||
import com.google.common.collect.Multimap; | |||
import java.util.Arrays; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.junit.Before; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.ExpectedException; | |||
import org.sonar.api.utils.System2; | |||
import org.sonar.core.permission.GlobalPermissions; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.DbTester; | |||
import org.sonar.db.user.GroupDao; | |||
import org.sonar.db.organization.OrganizationDto; | |||
import org.sonar.db.organization.OrganizationTesting; | |||
import org.sonar.db.user.GroupDto; | |||
import org.sonar.db.user.GroupMembershipDao; | |||
import org.sonar.db.user.UserDao; | |||
import org.sonar.db.user.UserDto; | |||
import org.sonar.db.user.UserGroupDao; | |||
import org.sonar.db.user.UserGroupDto; | |||
import org.sonar.server.exceptions.NotFoundException; | |||
import org.sonar.server.exceptions.UnauthorizedException; | |||
import org.sonar.server.organization.DefaultOrganizationProviderRule; | |||
import org.sonar.server.tester.UserSessionRule; | |||
import org.sonar.server.ws.WsTester; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.sonar.server.usergroups.ws.UserGroupsWsParameters.PARAM_GROUP_NAME; | |||
import static org.sonar.server.usergroups.ws.UserGroupsWsParameters.PARAM_LOGIN; | |||
import static org.sonar.db.organization.OrganizationTesting.newOrganizationDto; | |||
import static org.sonar.server.usergroups.ws.GroupWsSupport.PARAM_GROUP_NAME; | |||
import static org.sonar.server.usergroups.ws.GroupWsSupport.PARAM_LOGIN; | |||
import static org.sonar.server.usergroups.ws.GroupWsSupport.PARAM_ORGANIZATION_KEY; | |||
public class AddUserActionTest { | |||
@Rule | |||
public DbTester db = DbTester.create(System2.INSTANCE); | |||
@Rule | |||
public final UserSessionRule userSession = UserSessionRule.standalone(); | |||
public UserSessionRule userSession = UserSessionRule.standalone(); | |||
@Rule | |||
public final ExpectedException expectedException = ExpectedException.none(); | |||
public ExpectedException expectedException = ExpectedException.none(); | |||
private DefaultOrganizationProviderRule defaultOrganizationProvider = DefaultOrganizationProviderRule.create(db); | |||
private WsTester ws; | |||
private GroupDao groupDao; | |||
private UserDao userDao; | |||
private GroupMembershipDao groupMembershipDao; | |||
private UserGroupDao userGroupDao; | |||
private DbSession dbSession; | |||
@Before | |||
public void setUp() { | |||
dbSession = db.getSession(); | |||
DbClient dbClient = db.getDbClient(); | |||
groupDao = dbClient.groupDao(); | |||
userDao = dbClient.userDao(); | |||
groupMembershipDao = dbClient.groupMembershipDao(); | |||
userGroupDao = dbClient.userGroupDao(); | |||
ws = new WsTester(new UserGroupsWs(new AddUserAction(dbClient, new UserGroupFinder(dbClient), userSession))); | |||
ws = new WsTester(new UserGroupsWs(new AddUserAction(db.getDbClient(), userSession, newGroupWsSupport()))); | |||
} | |||
@Test | |||
public void add_user_nominal() throws Exception { | |||
GroupDto group = insertGroup("admins"); | |||
UserDto user = insertUser("my-admin"); | |||
dbSession.commit(); | |||
public void add_user_to_group_referenced_by_its_id() throws Exception { | |||
GroupDto group = db.users().insertGroup(defaultOrganizationProvider.getDto(), "admins"); | |||
UserDto user = db.users().insertUser("my-admin"); | |||
userSession.login("admin").setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam("id", group.getId().toString()) | |||
.setParam("login", user.getLogin()) | |||
.execute() | |||
.assertNoContent(); | |||
assertThat(groupMembershipDao.selectGroupsByLogins(dbSession, Arrays.asList(user.getLogin())).get(user.getLogin())) | |||
.containsOnly(group.getName()); | |||
assertThat(db.users().selectGroupIdsOfUser(user)).containsOnly(group.getId()); | |||
} | |||
@Test | |||
public void add_user_with_group_name() throws Exception { | |||
GroupDto group = insertGroup("group_name"); | |||
UserDto user = insertUser("user_login"); | |||
assertThat(groupMembershipDao.selectGroupsByLogins(dbSession, Arrays.asList(user.getLogin())).get(user.getLogin())) | |||
.isEmpty(); | |||
dbSession.commit(); | |||
public void add_user_to_group_referenced_by_its_name() throws Exception { | |||
GroupDto group = db.users().insertGroup(defaultOrganizationProvider.getDto(), "a-group"); | |||
UserDto user = db.users().insertUser("user_login"); | |||
userSession.login("admin").setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam(PARAM_GROUP_NAME, group.getName()) | |||
.setParam(PARAM_LOGIN, user.getLogin()) | |||
.execute() | |||
.assertNoContent(); | |||
assertThat(db.users().selectGroupIdsOfUser(user)).containsOnly(group.getId()); | |||
} | |||
@Test | |||
public void add_user_to_group_referenced_by_its_name_and_organization() throws Exception { | |||
OrganizationDto org = OrganizationTesting.insert(db, newOrganizationDto()); | |||
GroupDto group = db.users().insertGroup(org, "a-group"); | |||
UserDto user = db.users().insertUser("user_login"); | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam(PARAM_ORGANIZATION_KEY, org.getKey()) | |||
.setParam(PARAM_GROUP_NAME, group.getName()) | |||
.setParam(PARAM_LOGIN, user.getLogin()) | |||
.execute() | |||
.assertNoContent(); | |||
assertThat(groupMembershipDao.selectGroupsByLogins(dbSession, Arrays.asList(user.getLogin())).get(user.getLogin())) | |||
.containsOnly(group.getName()); | |||
assertThat(db.users().selectGroupIdsOfUser(user)).containsOnly(group.getId()); | |||
} | |||
@Test | |||
public void add_user_to_another_group() throws Exception { | |||
GroupDto admins = insertGroup("admins"); | |||
GroupDto users = insertGroup("users"); | |||
UserDto user = insertUser("my-admin"); | |||
insertMember(users.getId(), user.getId()); | |||
dbSession.commit(); | |||
OrganizationDto defaultOrg = defaultOrganizationProvider.getDto(); | |||
GroupDto admins = db.users().insertGroup(defaultOrg, "admins"); | |||
GroupDto users = db.users().insertGroup(defaultOrg, "users"); | |||
UserDto user = db.users().insertUser("my-admin"); | |||
db.users().insertMember(users, user); | |||
userSession.login("admin").setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam("id", admins.getId().toString()) | |||
.setParam("login", user.getLogin()) | |||
.execute() | |||
.assertNoContent(); | |||
assertThat(groupMembershipDao.selectGroupsByLogins(dbSession, Arrays.asList(user.getLogin())).get(user.getLogin())) | |||
.containsOnly(admins.getName(), users.getName()); | |||
assertThat(db.users().selectGroupIdsOfUser(user)).containsOnly(admins.getId(), users.getId()); | |||
} | |||
@Test | |||
public void add_user_already_in_group() throws Exception { | |||
GroupDto users = insertGroup("users"); | |||
UserDto user = insertUser("my-admin"); | |||
insertMember(users.getId(), user.getId()); | |||
dbSession.commit(); | |||
public void user_is_already_member_of_group() throws Exception { | |||
GroupDto users = db.users().insertGroup(defaultOrganizationProvider.getDto(), "users"); | |||
UserDto user = db.users().insertUser("my-admin"); | |||
db.users().insertMember(users, user); | |||
userSession.login("admin").setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam("id", users.getId().toString()) | |||
.setParam("login", user.getLogin()) | |||
.execute() | |||
.assertNoContent(); | |||
assertThat(groupMembershipDao.selectGroupsByLogins(dbSession, Arrays.asList(user.getLogin())).get(user.getLogin())) | |||
.containsOnly(users.getName()); | |||
// do not insert duplicated row | |||
assertThat(db.users().selectGroupIdsOfUser(user)).hasSize(1).containsOnly(users.getId()); | |||
} | |||
@Test | |||
public void add_another_user_to_group() throws Exception { | |||
GroupDto users = insertGroup("user"); | |||
UserDto user1 = insertUser("user1"); | |||
UserDto user2 = insertUser("user2"); | |||
insertMember(users.getId(), user1.getId()); | |||
dbSession.commit(); | |||
public void group_has_multiple_members() throws Exception { | |||
GroupDto users = db.users().insertGroup(defaultOrganizationProvider.getDto(), "user"); | |||
UserDto user1 = db.users().insertUser("user1"); | |||
UserDto user2 = db.users().insertUser("user2"); | |||
db.users().insertMember(users, user1); | |||
userSession.login("admin").setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam("id", users.getId().toString()) | |||
.setParam("login", user2.getLogin()) | |||
.execute() | |||
.assertNoContent(); | |||
Multimap<String, String> groupsByLogins = groupMembershipDao.selectGroupsByLogins(dbSession, Arrays.asList(user1.getLogin(), user2.getLogin())); | |||
assertThat(groupsByLogins.get(user1.getLogin())).containsOnly(users.getName()); | |||
assertThat(groupsByLogins.get(user2.getLogin())).containsOnly(users.getName()); | |||
assertThat(db.users().selectGroupIdsOfUser(user1)).containsOnly(users.getId()); | |||
assertThat(db.users().selectGroupIdsOfUser(user2)).containsOnly(users.getId()); | |||
} | |||
@Test | |||
public void unknown_group() throws Exception { | |||
UserDto user = insertUser("my-admin"); | |||
dbSession.commit(); | |||
public void fail_if_group_does_not_exist() throws Exception { | |||
UserDto user = db.users().insertUser("my-admin"); | |||
expectedException.expect(NotFoundException.class); | |||
userSession.login("admin").setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam("id", "42") | |||
.setParam("login", user.getLogin()) | |||
@@ -184,34 +173,41 @@ public class AddUserActionTest { | |||
} | |||
@Test | |||
public void unknown_user() throws Exception { | |||
GroupDto group = insertGroup("admins"); | |||
dbSession.commit(); | |||
public void fail_if_user_does_not_exist() throws Exception { | |||
GroupDto group = db.users().insertGroup(defaultOrganizationProvider.getDto(), "admins"); | |||
expectedException.expect(NotFoundException.class); | |||
userSession.login("admin").setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam("id", group.getId().toString()) | |||
.setParam("login", "my-admin") | |||
.execute(); | |||
} | |||
@Test | |||
public void fail_if_not_administrator() throws Exception { | |||
GroupDto group = db.users().insertGroup(defaultOrganizationProvider.getDto(), "admins"); | |||
UserDto user = db.users().insertUser("my-admin"); | |||
expectedException.expect(UnauthorizedException.class); | |||
newRequest() | |||
.setParam("id", group.getId().toString()) | |||
.setParam("login", user.getLogin()) | |||
.execute(); | |||
} | |||
private WsTester.TestRequest newRequest() { | |||
return ws.newPostRequest("api/user_groups", "add_user"); | |||
} | |||
private GroupDto insertGroup(String groupName) { | |||
return groupDao.insert(dbSession, new GroupDto() | |||
.setName(groupName) | |||
.setDescription(StringUtils.capitalize(groupName))); | |||
private void loginAsAdmin() { | |||
userSession.login("admin").setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); | |||
} | |||
private UserDto insertUser(String login) { | |||
return userDao.insert(dbSession, new UserDto().setLogin(login).setName(login).setActive(true)); | |||
private GroupWsSupport newGroupWsSupport() { | |||
return new GroupWsSupport(db.getDbClient(), defaultOrganizationProvider); | |||
} | |||
private void insertMember(long groupId, long userId) { | |||
userGroupDao.insert(dbSession, new UserGroupDto().setGroupId(groupId).setUserId(userId)); | |||
} | |||
} |
@@ -19,7 +19,6 @@ | |||
*/ | |||
package org.sonar.server.usergroups.ws; | |||
import java.net.HttpURLConnection; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.junit.Before; | |||
import org.junit.Rule; | |||
@@ -27,16 +26,19 @@ import org.junit.Test; | |||
import org.junit.rules.ExpectedException; | |||
import org.sonar.api.utils.System2; | |||
import org.sonar.core.permission.GlobalPermissions; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.DbTester; | |||
import org.sonar.db.user.GroupDao; | |||
import org.sonar.db.organization.OrganizationDto; | |||
import org.sonar.db.organization.OrganizationTesting; | |||
import org.sonar.db.user.GroupDto; | |||
import org.sonar.server.exceptions.ForbiddenException; | |||
import org.sonar.server.exceptions.ServerException; | |||
import org.sonar.server.organization.DefaultOrganization; | |||
import org.sonar.server.organization.DefaultOrganizationProviderRule; | |||
import org.sonar.server.tester.UserSessionRule; | |||
import org.sonar.server.ws.WsTester; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.sonar.db.organization.OrganizationTesting.newOrganizationDto; | |||
public class CreateActionTest { | |||
@@ -47,37 +49,62 @@ public class CreateActionTest { | |||
@Rule | |||
public ExpectedException expectedException = ExpectedException.none(); | |||
private DefaultOrganizationProviderRule defaultOrganizationProvider = DefaultOrganizationProviderRule.create(db); | |||
private WsTester ws; | |||
private GroupDao groupDao; | |||
private DbSession dbSession; | |||
@Before | |||
public void setUp() { | |||
DbClient dbClient = db.getDbClient(); | |||
groupDao = dbClient.groupDao(); | |||
dbSession = db.getSession(); | |||
ws = new WsTester(new UserGroupsWs(new CreateAction(db.getDbClient(), userSession, newGroupWsSupport()))); | |||
} | |||
@Test | |||
public void create_group_on_default_organization() throws Exception { | |||
loginAsAdmin(); | |||
ws = new WsTester(new UserGroupsWs(new CreateAction(dbClient, userSession, new UserGroupUpdater(dbClient)))); | |||
newRequest() | |||
.setParam("name", "some-product-bu") | |||
.setParam("description", "Business Unit for Some Awesome Product") | |||
.execute() | |||
.assertJson("{" + | |||
" \"group\": {" + | |||
" \"organization\": \"" + getDefaultOrganization().getKey() + "\"," + | |||
" \"name\": \"some-product-bu\"," + | |||
" \"description\": \"Business Unit for Some Awesome Product\"," + | |||
" \"membersCount\": 0" + | |||
" }" + | |||
"}"); | |||
assertThat(db.users().selectGroup(defaultOrganizationProvider.getDto(), "some-product-bu")).isPresent(); | |||
} | |||
@Test | |||
public void create_nominal() throws Exception { | |||
public void create_group_on_specific_organization() throws Exception { | |||
OrganizationDto org = OrganizationTesting.insert(db, newOrganizationDto()); | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam("organization", org.getKey()) | |||
.setParam("name", "some-product-bu") | |||
.setParam("description", "Business Unit for Some Awesome Product") | |||
.execute().assertJson("{" + | |||
.execute() | |||
.assertJson("{" + | |||
" \"group\": {" + | |||
" \"organization\": \"" + org.getKey() + "\"," + | |||
" \"name\": \"some-product-bu\"," + | |||
" \"description\": \"Business Unit for Some Awesome Product\"," + | |||
" \"membersCount\": 0" + | |||
" }" + | |||
"}"); | |||
GroupDto createdGroup = db.users().selectGroup(org, "some-product-bu").get(); | |||
assertThat(createdGroup.getId()).isNotNull(); | |||
assertThat(createdGroup.getOrganizationUuid()).isEqualTo(org.getUuid()); | |||
} | |||
@Test(expected = ForbiddenException.class) | |||
public void require_admin_permission() throws Exception { | |||
userSession.login("not-admin"); | |||
newRequest() | |||
.setParam("name", "some-product-bu") | |||
.setParam("description", "Business Unit for Some Awesome Product") | |||
@@ -85,7 +112,7 @@ public class CreateActionTest { | |||
} | |||
@Test(expected = IllegalArgumentException.class) | |||
public void name_too_short() throws Exception { | |||
public void fail_if_name_is_too_short() throws Exception { | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam("name", "") | |||
@@ -93,7 +120,7 @@ public class CreateActionTest { | |||
} | |||
@Test(expected = IllegalArgumentException.class) | |||
public void name_too_long() throws Exception { | |||
public void fail_if_name_is_too_long() throws Exception { | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam("name", StringUtils.repeat("a", 255 + 1)) | |||
@@ -101,7 +128,7 @@ public class CreateActionTest { | |||
} | |||
@Test(expected = IllegalArgumentException.class) | |||
public void forbidden_name() throws Exception { | |||
public void fail_if_name_is_anyone() throws Exception { | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam("name", "AnYoNe") | |||
@@ -109,27 +136,62 @@ public class CreateActionTest { | |||
} | |||
@Test | |||
public void non_unique_name() throws Exception { | |||
String groupName = "conflicting-name"; | |||
groupDao.insert(dbSession, new GroupDto() | |||
.setName(groupName)); | |||
db.commit(); | |||
public void fail_if_group_with_same_name_already_exists() throws Exception { | |||
GroupDto group = db.users().insertGroup(defaultOrganizationProvider.getDto(), "the-group"); | |||
expectedException.expect(ServerException.class); | |||
expectedException.expectMessage("already taken"); | |||
expectedException.expectMessage("Group '" + group.getName() + "' already exists"); | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam("name", groupName) | |||
.execute().assertStatus(HttpURLConnection.HTTP_CONFLICT); | |||
.setParam("name", group.getName()) | |||
.execute(); | |||
} | |||
@Test | |||
public void fail_if_group_with_same_name_already_exists_in_the_organization() throws Exception { | |||
OrganizationDto org = OrganizationTesting.insert(db, newOrganizationDto()); | |||
GroupDto group = db.users().insertGroup(org, "the-group"); | |||
expectedException.expect(ServerException.class); | |||
expectedException.expectMessage("Group '" + group.getName() + "' already exists"); | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam("organization", org.getKey()) | |||
.setParam("name", group.getName()) | |||
.execute(); | |||
} | |||
@Test | |||
public void add_group_with_a_name_that_already_exists_in_another_organization() throws Exception { | |||
String name = "the-group"; | |||
OrganizationDto org1 = OrganizationTesting.insert(db, newOrganizationDto()); | |||
OrganizationDto org2 = OrganizationTesting.insert(db, newOrganizationDto()); | |||
GroupDto group = db.users().insertGroup(org1, name); | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam("organization", org2.getKey()) | |||
.setParam("name", name) | |||
.execute() | |||
.assertJson("{" + | |||
" \"group\": {" + | |||
" \"organization\": \"" + org2.getKey() + "\"," + | |||
" \"name\": \"" + group.getName() + "\"," + | |||
" }" + | |||
"}"); | |||
assertThat(db.users().selectGroups(org1)).extracting(GroupDto::getName).containsOnly(name); | |||
assertThat(db.users().selectGroups(org2)).extracting(GroupDto::getName).containsOnly(name); | |||
} | |||
@Test(expected = IllegalArgumentException.class) | |||
public void description_too_long() throws Exception { | |||
public void fail_if_description_is_too_long() throws Exception { | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam("name", "long-group-description-is-looooooooooooong") | |||
.setParam("description", StringUtils.repeat("a", 200 + 1)) | |||
.setParam("name", "long-desc") | |||
.setParam("description", StringUtils.repeat("a", 1_000)) | |||
.execute(); | |||
} | |||
@@ -140,4 +202,12 @@ public class CreateActionTest { | |||
private void loginAsAdmin() { | |||
userSession.login("admin").setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); | |||
} | |||
private GroupWsSupport newGroupWsSupport() { | |||
return new GroupWsSupport(db.getDbClient(), defaultOrganizationProvider); | |||
} | |||
private DefaultOrganization getDefaultOrganization() { | |||
return defaultOrganizationProvider.get(); | |||
} | |||
} |
@@ -28,30 +28,24 @@ import org.sonar.api.config.MapSettings; | |||
import org.sonar.api.config.Settings; | |||
import org.sonar.api.utils.System2; | |||
import org.sonar.api.web.UserRole; | |||
import org.sonar.core.permission.GlobalPermissions; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.DbTester; | |||
import org.sonar.db.permission.GroupPermissionDao; | |||
import org.sonar.db.permission.GroupPermissionDto; | |||
import org.sonar.db.permission.UserPermissionDto; | |||
import org.sonar.db.permission.template.PermissionTemplateDao; | |||
import org.sonar.db.user.GroupDao; | |||
import org.sonar.db.user.GroupDbTester; | |||
import org.sonar.db.component.ComponentDbTester; | |||
import org.sonar.db.component.ComponentDto; | |||
import org.sonar.db.component.ComponentTesting; | |||
import org.sonar.db.organization.OrganizationDto; | |||
import org.sonar.db.organization.OrganizationTesting; | |||
import org.sonar.db.user.GroupDto; | |||
import org.sonar.db.user.RoleDao; | |||
import org.sonar.db.user.UserDbTester; | |||
import org.sonar.db.user.UserDto; | |||
import org.sonar.db.user.UserGroupDao; | |||
import org.sonar.db.user.UserGroupDto; | |||
import org.sonar.server.exceptions.NotFoundException; | |||
import org.sonar.server.organization.DefaultOrganizationProviderRule; | |||
import org.sonar.server.tester.UserSessionRule; | |||
import org.sonar.server.ws.WsTester; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.sonar.db.user.GroupTesting.newGroupDto; | |||
import static org.sonar.db.user.UserTesting.newUserDto; | |||
import static org.sonar.server.usergroups.ws.UserGroupsWsParameters.PARAM_GROUP_NAME; | |||
import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN; | |||
import static org.sonar.db.organization.OrganizationTesting.newOrganizationDto; | |||
import static org.sonar.server.usergroups.ws.GroupWsSupport.PARAM_GROUP_NAME; | |||
import static org.sonar.server.usergroups.ws.GroupWsSupport.PARAM_ORGANIZATION_KEY; | |||
public class DeleteActionTest { | |||
@@ -61,127 +55,164 @@ public class DeleteActionTest { | |||
public ExpectedException expectedException = ExpectedException.none(); | |||
@Rule | |||
public DbTester db = DbTester.create(System2.INSTANCE); | |||
GroupDbTester groupDb = new GroupDbTester(db); | |||
UserDbTester userDb = new UserDbTester(db); | |||
DbClient dbClient = db.getDbClient(); | |||
DbSession dbSession = db.getSession(); | |||
GroupDao groupDao = dbClient.groupDao(); | |||
UserGroupDao userGroupDao = dbClient.userGroupDao(); | |||
RoleDao roleDao = dbClient.roleDao(); | |||
PermissionTemplateDao permissionTemplateDao = dbClient.permissionTemplateDao(); | |||
GroupPermissionDao groupPermissionDao = dbClient.groupPermissionDao(); | |||
private ComponentDbTester componentTester = new ComponentDbTester(db); | |||
private DefaultOrganizationProviderRule defaultOrganizationProvider = DefaultOrganizationProviderRule.create(db); | |||
private GroupDto defaultGroup; | |||
private WsTester ws; | |||
private Long defaultGroupId; | |||
@Before | |||
public void setUp() { | |||
defaultGroup = db.users().insertGroup(defaultOrganizationProvider.getDto(), CoreProperties.CORE_DEFAULT_GROUP_DEFAULT_VALUE); | |||
Settings settings = new MapSettings().setProperty(CoreProperties.CORE_DEFAULT_GROUP, CoreProperties.CORE_DEFAULT_GROUP_DEFAULT_VALUE); | |||
GroupDto defaultGroup = groupDao.insert(dbSession, new GroupDto().setName(CoreProperties.CORE_DEFAULT_GROUP_DEFAULT_VALUE)); | |||
defaultGroupId = defaultGroup.getId(); | |||
dbSession.commit(); | |||
ws = new WsTester(new UserGroupsWs( | |||
new DeleteAction( | |||
dbClient, | |||
new UserGroupFinder(dbClient), | |||
db.getDbClient(), | |||
userSession, | |||
settings))); | |||
newGroupWsSupport(), | |||
settings, defaultOrganizationProvider))); | |||
} | |||
@Test | |||
public void delete_simple() throws Exception { | |||
GroupDto group = groupDao.insert(dbSession, new GroupDto().setName("to-delete")); | |||
dbSession.commit(); | |||
public void delete_by_id() throws Exception { | |||
GroupDto group = db.users().insertGroup(defaultOrganizationProvider.getDto(), "to-delete"); | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam("id", group.getId().toString()) | |||
.execute().assertNoContent(); | |||
.execute() | |||
.assertNoContent(); | |||
assertThat(db.users().selectGroupById(group.getId())).isNull(); | |||
} | |||
@Test | |||
public void delete_with_group_name() throws Exception { | |||
GroupDto group = groupDao.insert(dbSession, newGroupDto().setName("group_name")); | |||
assertThat(groupDao.selectById(dbSession, group.getId())).isNotNull(); | |||
dbSession.commit(); | |||
public void delete_by_name_on_default_organization() throws Exception { | |||
GroupDto group = db.users().insertGroup(defaultOrganizationProvider.getDto(), "to-delete"); | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam(PARAM_GROUP_NAME, group.getName()) | |||
.execute().assertNoContent(); | |||
.execute() | |||
.assertNoContent(); | |||
assertThat(db.users().selectGroupById(group.getId())).isNull(); | |||
} | |||
@Test | |||
public void delete_by_name_and_organization() throws Exception { | |||
OrganizationDto org = OrganizationTesting.insert(db, newOrganizationDto()); | |||
GroupDto group = db.users().insertGroup(org, "to-delete"); | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam(PARAM_ORGANIZATION_KEY, org.getKey()) | |||
.setParam(PARAM_GROUP_NAME, group.getName()) | |||
.execute() | |||
.assertNoContent(); | |||
assertThat(db.users().selectGroupById(group.getId())).isNull(); | |||
} | |||
@Test | |||
public void delete_by_name_fails_if_organization_is_not_correct() throws Exception { | |||
OrganizationDto org = newOrganizationDto().setUuid("org1"); | |||
OrganizationTesting.insert(db, org); | |||
loginAsAdmin(); | |||
expectedException.expect(NotFoundException.class); | |||
expectedException.expectMessage("No organization with key 'org1'"); | |||
assertThat(groupDao.selectById(dbSession, group.getId())).isNull(); | |||
newRequest() | |||
.setParam(PARAM_ORGANIZATION_KEY, "org1") | |||
.setParam(PARAM_GROUP_NAME, "a-group") | |||
.execute(); | |||
} | |||
@Test | |||
public void delete_with_members() throws Exception { | |||
GroupDto group = groupDao.insert(dbSession, new GroupDto().setName("to-delete")); | |||
userGroupDao.insert(dbSession, new UserGroupDto().setGroupId(group.getId()).setUserId(42L)); | |||
dbSession.commit(); | |||
public void delete_members() throws Exception { | |||
GroupDto group = db.users().insertGroup(defaultOrganizationProvider.getDto(), "to-be-deleted"); | |||
UserDto user = db.users().insertUser("a-user"); | |||
db.users().insertMember(group, user); | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam("id", group.getId().toString()) | |||
.execute().assertNoContent(); | |||
.execute() | |||
.assertNoContent(); | |||
assertThat(db.select("SELECT group_id FROM groups_users")).isEmpty(); | |||
assertThat(db.countRowsOfTable("groups_users")).isEqualTo(0); | |||
} | |||
@Test | |||
public void delete_with_permissions() throws Exception { | |||
GroupDto group = groupDao.insert(dbSession, new GroupDto().setName("to-delete")); | |||
roleDao.insertGroupRole(dbSession, new GroupPermissionDto().setGroupId(group.getId()).setResourceId(42L).setRole(UserRole.ADMIN)); | |||
dbSession.commit(); | |||
public void delete_permissions() throws Exception { | |||
GroupDto group = db.users().insertGroup(defaultOrganizationProvider.getDto(), "to-be-deleted"); | |||
ComponentDto project = componentTester.insertComponent(ComponentTesting.newProjectDto()); | |||
db.users().insertProjectPermissionOnGroup(group, UserRole.ADMIN, project); | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam("id", group.getId().toString()) | |||
.execute().assertNoContent(); | |||
.execute() | |||
.assertNoContent(); | |||
assertThat(db.select("SELECT group_id FROM group_roles")).isEmpty(); | |||
assertThat(db.countRowsOfTable("group_roles")).isEqualTo(0); | |||
} | |||
@Test | |||
public void delete_with_permission_templates() throws Exception { | |||
GroupDto group = groupDao.insert(dbSession, new GroupDto().setName("to-delete")); | |||
permissionTemplateDao.insertGroupPermission(dbSession, 42L, group.getId(), UserRole.ADMIN); | |||
dbSession.commit(); | |||
public void delete_permission_templates() throws Exception { | |||
GroupDto group = db.users().insertGroup(defaultOrganizationProvider.getDto(), "to-be-deleted"); | |||
// TODO | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam("id", group.getId().toString()) | |||
.execute().assertNoContent(); | |||
assertThat(db.select("SELECT group_id FROM perm_templates_groups")).isEmpty(); | |||
assertThat(db.countRowsOfTable("perm_templates_groups")).isEqualTo(0); | |||
} | |||
@Test(expected = NotFoundException.class) | |||
public void not_found() throws Exception { | |||
public void fail_if_id_does_not_exist() throws Exception { | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam("id", String.valueOf(defaultGroupId + 1L)) | |||
.setParam("id", String.valueOf(defaultGroup.getId() + 123)) | |||
.execute(); | |||
} | |||
@Test(expected = IllegalArgumentException.class) | |||
public void cannot_delete_default_group() throws Exception { | |||
public void cannot_delete_default_group_of_default_organization() throws Exception { | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam("id", defaultGroup.getId().toString()) | |||
.execute(); | |||
} | |||
@Test | |||
public void delete_group_of_an_organization_even_if_name_is_default_group_of_default_organization() throws Exception { | |||
OrganizationDto org = OrganizationTesting.insert(db, newOrganizationDto()); | |||
GroupDto group = db.users().insertGroup(org, defaultGroup.getName()); | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam("id", defaultGroupId.toString()) | |||
.setParam("id", group.getId().toString()) | |||
.execute(); | |||
assertThat(db.users().selectGroupById(defaultGroup.getId())).isNotNull(); | |||
assertThat(db.users().selectGroupById(group.getId())).isNull(); | |||
} | |||
@Test | |||
public void cannot_delete_last_system_admin_group() throws Exception { | |||
GroupDto group = groupDb.insertGroup(newGroupDto().setName("system-admins")); | |||
roleDao.insertGroupRole(dbSession, new GroupPermissionDto().setGroupId(group.getId()).setRole(GlobalPermissions.SYSTEM_ADMIN)); | |||
assertThat(groupPermissionDao.countGroups(dbSession, GlobalPermissions.SYSTEM_ADMIN, null)).isEqualTo(1); | |||
dbSession.commit(); | |||
GroupDto group = db.users().insertGroup(defaultOrganizationProvider.getDto(), "system-admins"); | |||
db.users().insertPermissionOnGroup(group, SYSTEM_ADMIN); | |||
loginAsAdmin(); | |||
expectedException.expect(IllegalArgumentException.class); | |||
expectedException.expectMessage("The last system admin group 'system-admins' cannot be deleted"); | |||
expectedException.expectMessage("The last system admin group cannot be deleted"); | |||
newRequest() | |||
.setParam(PARAM_GROUP_NAME, group.getName()) | |||
@@ -189,12 +220,12 @@ public class DeleteActionTest { | |||
} | |||
@Test | |||
public void can_delete_system_admin_group_if_not_last() throws Exception { | |||
GroupDto funkyAdmins = groupDb.insertGroup(newGroupDto().setName("funky-admins")); | |||
roleDao.insertGroupRole(dbSession, new GroupPermissionDto().setGroupId(funkyAdmins.getId()).setRole(GlobalPermissions.SYSTEM_ADMIN)); | |||
GroupDto boringAdmins = groupDb.insertGroup(newGroupDto().setName("boring-admins")); | |||
roleDao.insertGroupRole(dbSession, new GroupPermissionDto().setGroupId(boringAdmins.getId()).setRole(GlobalPermissions.SYSTEM_ADMIN)); | |||
dbSession.commit(); | |||
public void delete_system_admin_group_if_not_last() throws Exception { | |||
OrganizationDto defaultOrg = defaultOrganizationProvider.getDto(); | |||
GroupDto funkyAdmins = db.users().insertGroup(defaultOrg, "funky-admins"); | |||
db.users().insertPermissionOnGroup(funkyAdmins, SYSTEM_ADMIN); | |||
GroupDto boringAdmins = db.users().insertGroup(defaultOrg, "boring-admins"); | |||
db.users().insertPermissionOnGroup(boringAdmins, SYSTEM_ADMIN); | |||
loginAsAdmin(); | |||
@@ -202,29 +233,32 @@ public class DeleteActionTest { | |||
.setParam(PARAM_GROUP_NAME, boringAdmins.getName()) | |||
.execute(); | |||
assertThat(groupPermissionDao.countGroups(dbSession, GlobalPermissions.SYSTEM_ADMIN, null)).isEqualTo(1); | |||
assertThat(db.getDbClient().groupPermissionDao().countGroups(db.getSession(), SYSTEM_ADMIN, null)).isEqualTo(1); | |||
} | |||
@Test | |||
public void can_delete_last_system_admin_group_if_admin_user_left() throws Exception { | |||
GroupDto lastGroup = groupDb.insertGroup(newGroupDto().setName("last-group")); | |||
roleDao.insertGroupRole(dbSession, new GroupPermissionDto().setGroupId(lastGroup.getId()).setRole(GlobalPermissions.SYSTEM_ADMIN)); | |||
UserDto bigBoss = userDb.insertUser(newUserDto("big.boss", "Big Boss", "big@boss.com")); | |||
dbClient.userPermissionDao().insert(dbSession, new UserPermissionDto(GlobalPermissions.SYSTEM_ADMIN, bigBoss.getId(), null)); | |||
dbSession.commit(); | |||
public void delete_last_system_admin_group_if_admin_user_left() throws Exception { | |||
GroupDto lastGroup = db.users().insertGroup(defaultOrganizationProvider.getDto(), "last-group"); | |||
db.users().insertPermissionOnGroup(lastGroup, SYSTEM_ADMIN); | |||
UserDto bigBoss = db.users().insertUser("big.boss"); | |||
db.users().insertPermissionOnUser(bigBoss, SYSTEM_ADMIN); | |||
loginAsAdmin(); | |||
newRequest().setParam(PARAM_GROUP_NAME, lastGroup.getName()).execute(); | |||
assertThat(groupDao.selectById(dbSession, lastGroup.getId())).isNull(); | |||
assertThat(db.users().selectGroupById(lastGroup.getId())).isNull(); | |||
} | |||
private void loginAsAdmin() { | |||
userSession.login("admin").setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); | |||
userSession.login("admin").setGlobalPermissions(SYSTEM_ADMIN); | |||
} | |||
private WsTester.TestRequest newRequest() { | |||
return ws.newPostRequest("api/user_groups", "delete"); | |||
} | |||
private GroupWsSupport newGroupWsSupport() { | |||
return new GroupWsSupport(db.getDbClient(), defaultOrganizationProvider); | |||
} | |||
} |
@@ -0,0 +1,89 @@ | |||
/* | |||
* 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 org.sonar.server.usergroups.ws; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.ExpectedException; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.sonar.server.usergroups.ws.GroupWsRef.fromName; | |||
public class GroupWsRefTest { | |||
@Rule | |||
public ExpectedException expectedException = ExpectedException.none(); | |||
@Test | |||
public void test_ref_by_id() { | |||
GroupWsRef ref = GroupWsRef.fromId(10L); | |||
assertThat(ref.hasId()).isTrue(); | |||
assertThat(ref.getId()).isEqualTo(10L); | |||
assertThat(ref.isAnyone()).isFalse(); | |||
} | |||
@Test | |||
public void test_ref_by_name() { | |||
GroupWsRef ref = fromName("ORG1", "the-group"); | |||
assertThat(ref.hasId()).isFalse(); | |||
assertThat(ref.getOrganizationKey()).isEqualTo("ORG1"); | |||
assertThat(ref.getName()).isEqualTo("the-group"); | |||
assertThat(ref.isAnyone()).isFalse(); | |||
} | |||
@Test | |||
public void test_equals_and_hashCode() { | |||
GroupWsRef refId1 = GroupWsRef.fromId(10L); | |||
GroupWsRef refId2 = GroupWsRef.fromId(11L); | |||
assertThat(refId1.equals(refId1)).isTrue(); | |||
assertThat(refId1.equals(GroupWsRef.fromId(10L))).isTrue(); | |||
assertThat(refId1.hashCode()).isEqualTo(GroupWsRef.fromId(10L).hashCode()); | |||
assertThat(refId1.equals(refId2)).isFalse(); | |||
GroupWsRef refName1 = fromName("ORG1", "the-group"); | |||
GroupWsRef refName2 = fromName("ORG1", "the-group2"); | |||
GroupWsRef refName3 = fromName("ORG2", "the-group2"); | |||
assertThat(refName1.equals(refName1)).isTrue(); | |||
assertThat(refName1.equals(fromName("ORG1", "the-group"))).isTrue(); | |||
assertThat(refName1.hashCode()).isEqualTo(fromName("ORG1", "the-group").hashCode()); | |||
assertThat(refName1.equals(refName2)).isFalse(); | |||
assertThat(refName2.equals(refName3)).isFalse(); | |||
} | |||
@Test | |||
public void test_toString() { | |||
GroupWsRef refId = GroupWsRef.fromId(10L); | |||
assertThat(refId.toString()).isEqualTo("GroupWsRef{id=10, organizationKey='null', name='null'}"); | |||
} | |||
@Test | |||
public void reference_anyone_by_its_name() { | |||
GroupWsRef ref = GroupWsRef.fromName("my-org", "Anyone"); | |||
assertThat(ref.getOrganizationKey()).isEqualTo("my-org"); | |||
assertThat(ref.getName()).isEqualTo("Anyone"); | |||
assertThat(ref.isAnyone()).isTrue(); | |||
// case-insensitive | |||
ref = GroupWsRef.fromName("my-org", "anyone"); | |||
assertThat(ref.getOrganizationKey()).isEqualTo("my-org"); | |||
assertThat(ref.getName()).isEqualTo("anyone"); | |||
assertThat(ref.isAnyone()).isTrue(); | |||
} | |||
} |
@@ -19,145 +19,136 @@ | |||
*/ | |||
package org.sonar.server.usergroups.ws; | |||
import java.util.Arrays; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.junit.Before; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.ExpectedException; | |||
import org.sonar.api.utils.System2; | |||
import org.sonar.core.permission.GlobalPermissions; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.DbTester; | |||
import org.sonar.db.user.GroupDao; | |||
import org.sonar.db.organization.OrganizationDto; | |||
import org.sonar.db.organization.OrganizationTesting; | |||
import org.sonar.db.user.GroupDto; | |||
import org.sonar.db.user.GroupMembershipDao; | |||
import org.sonar.db.user.UserDao; | |||
import org.sonar.db.user.UserDto; | |||
import org.sonar.db.user.UserGroupDao; | |||
import org.sonar.db.user.UserGroupDto; | |||
import org.sonar.server.exceptions.NotFoundException; | |||
import org.sonar.server.organization.DefaultOrganizationProviderRule; | |||
import org.sonar.server.tester.UserSessionRule; | |||
import org.sonar.server.ws.WsTester; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.sonar.server.usergroups.ws.UserGroupsWsParameters.PARAM_GROUP_NAME; | |||
import static org.sonar.server.usergroups.ws.UserGroupsWsParameters.PARAM_LOGIN; | |||
import static org.sonar.server.usergroups.ws.GroupWsSupport.PARAM_GROUP_NAME; | |||
import static org.sonar.server.usergroups.ws.GroupWsSupport.PARAM_LOGIN; | |||
import static org.sonar.server.usergroups.ws.GroupWsSupport.PARAM_ORGANIZATION_KEY; | |||
public class RemoveUserActionTest { | |||
@Rule | |||
public DbTester db = DbTester.create(System2.INSTANCE); | |||
@Rule | |||
public final UserSessionRule userSession = UserSessionRule.standalone(); | |||
public UserSessionRule userSession = UserSessionRule.standalone(); | |||
@Rule | |||
public final ExpectedException expectedException = ExpectedException.none(); | |||
public ExpectedException expectedException = ExpectedException.none(); | |||
private DefaultOrganizationProviderRule defaultOrganizationProvider = DefaultOrganizationProviderRule.create(db); | |||
private WsTester ws; | |||
private GroupDao groupDao; | |||
private UserDao userDao; | |||
private GroupMembershipDao groupMembershipDao; | |||
private UserGroupDao userGroupDao; | |||
private DbSession dbSession; | |||
@Before | |||
public void setUp() { | |||
dbSession = db.getSession(); | |||
org.sonar.db.DbClient dbClient = db.getDbClient(); | |||
groupDao = dbClient.groupDao(); | |||
userDao = dbClient.userDao(); | |||
groupMembershipDao = dbClient.groupMembershipDao(); | |||
userGroupDao = dbClient.userGroupDao(); | |||
ws = new WsTester(new UserGroupsWs(new RemoveUserAction(dbClient, userSession))); | |||
GroupWsSupport groupSupport = new GroupWsSupport(db.getDbClient(), defaultOrganizationProvider); | |||
ws = new WsTester(new UserGroupsWs(new RemoveUserAction(db.getDbClient(), userSession, groupSupport))); | |||
} | |||
@Test | |||
public void remove_user_not_in_group() throws Exception { | |||
GroupDto group = insertGroup("admins"); | |||
UserDto user = insertUser("my-admin"); | |||
dbSession.commit(); | |||
public void does_nothing_if_user_is_not_in_group() throws Exception { | |||
GroupDto group = db.users().insertGroup(defaultOrganizationProvider.getDto(), "admins"); | |||
UserDto user = db.users().insertUser("my-admin"); | |||
userSession.login("admin").setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam("id", group.getId().toString()) | |||
.setParam("login", user.getLogin()) | |||
.execute() | |||
.assertNoContent(); | |||
assertThat(groupMembershipDao.selectGroupsByLogins(dbSession, Arrays.asList(user.getLogin())).get(user.getLogin())) | |||
.isEmpty(); | |||
assertThat(db.users().selectGroupIdsOfUser(user)).isEmpty(); | |||
} | |||
@Test | |||
public void remove_user_nominal() throws Exception { | |||
GroupDto users = insertGroup("users"); | |||
UserDto user = insertUser("my-admin"); | |||
insertMember(users.getId(), user.getId()); | |||
dbSession.commit(); | |||
userSession.login("admin").setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); | |||
public void remove_user_by_group_id() throws Exception { | |||
GroupDto users = db.users().insertGroup(defaultOrganizationProvider.getDto(), "users"); | |||
UserDto user = db.users().insertUser("my-admin"); | |||
db.users().insertMember(users, user); | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam("id", users.getId().toString()) | |||
.setParam("login", user.getLogin()) | |||
.execute() | |||
.assertNoContent(); | |||
assertThat(groupMembershipDao.selectGroupsByLogins(dbSession, Arrays.asList(user.getLogin())).get(user.getLogin())) | |||
.isEmpty(); | |||
assertThat(db.users().selectGroupIdsOfUser(user)).isEmpty(); | |||
} | |||
@Test | |||
public void remove_user_by_group_name() throws Exception { | |||
userSession.login("admin").setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); | |||
GroupDto group = insertGroup("group_name"); | |||
UserDto user = insertUser("user_login"); | |||
insertMember(group.getId(), user.getId()); | |||
assertThat(groupMembershipDao.selectGroupsByLogins(dbSession, Arrays.asList(user.getLogin())).get(user.getLogin())) | |||
.isNotEmpty(); | |||
db.commit(); | |||
public void remove_user_by_group_name_in_default_organization() throws Exception { | |||
GroupDto group = db.users().insertGroup(defaultOrganizationProvider.getDto(), "group_name"); | |||
UserDto user = db.users().insertUser("user_login"); | |||
db.users().insertMember(group, user); | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam(PARAM_GROUP_NAME, group.getName()) | |||
.setParam(PARAM_LOGIN, user.getLogin()) | |||
.execute() | |||
.assertNoContent(); | |||
assertThat(groupMembershipDao.selectGroupsByLogins(dbSession, Arrays.asList(user.getLogin())).get(user.getLogin())) | |||
.isEmpty(); | |||
assertThat(db.users().selectGroupIdsOfUser(user)).isEmpty(); | |||
} | |||
@Test | |||
public void remove_user_only_from_one_group() throws Exception { | |||
GroupDto users = insertGroup("user"); | |||
GroupDto admins = insertGroup("admins"); | |||
UserDto user = insertUser("user"); | |||
insertMember(users.getId(), user.getId()); | |||
insertMember(admins.getId(), user.getId()); | |||
dbSession.commit(); | |||
public void remove_user_by_group_name_in_specific_organization() throws Exception { | |||
OrganizationDto org = OrganizationTesting.insert(db, OrganizationTesting.newOrganizationDto()); | |||
GroupDto group = db.users().insertGroup(org, "a_group"); | |||
UserDto user = db.users().insertUser("user_login"); | |||
db.users().insertMember(group, user); | |||
userSession.login("admin").setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam(PARAM_ORGANIZATION_KEY, org.getKey()) | |||
.setParam(PARAM_GROUP_NAME, group.getName()) | |||
.setParam(PARAM_LOGIN, user.getLogin()) | |||
.execute() | |||
.assertNoContent(); | |||
assertThat(db.users().selectGroupIdsOfUser(user)).isEmpty(); | |||
} | |||
@Test | |||
public void remove_user_only_from_one_group() throws Exception { | |||
OrganizationDto defaultOrg = defaultOrganizationProvider.getDto(); | |||
GroupDto users = db.users().insertGroup(defaultOrg, "user"); | |||
GroupDto admins = db.users().insertGroup(defaultOrg, "admins"); | |||
UserDto user = db.users().insertUser("user"); | |||
db.users().insertMember(users, user); | |||
db.users().insertMember(admins, user); | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam("id", admins.getId().toString()) | |||
.setParam("login", user.getLogin()) | |||
.execute() | |||
.assertNoContent(); | |||
assertThat(groupMembershipDao.selectGroupsByLogins(dbSession, Arrays.asList(user.getLogin())).get(user.getLogin())) | |||
.containsOnly(users.getName()); | |||
assertThat(db.users().selectGroupIdsOfUser(user)).containsOnly(users.getId()); | |||
} | |||
@Test | |||
public void unknown_group() throws Exception { | |||
UserDto user = insertUser("my-admin"); | |||
dbSession.commit(); | |||
public void fail_if_unknown_group() throws Exception { | |||
UserDto user = db.users().insertUser("my-admin"); | |||
expectedException.expect(NotFoundException.class); | |||
userSession.login("admin").setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam("id", "42") | |||
.setParam("login", user.getLogin()) | |||
@@ -165,13 +156,12 @@ public class RemoveUserActionTest { | |||
} | |||
@Test | |||
public void unknown_user() throws Exception { | |||
GroupDto group = insertGroup("admins"); | |||
dbSession.commit(); | |||
public void fail_if_unknown_user() throws Exception { | |||
GroupDto group = db.users().insertGroup(defaultOrganizationProvider.getDto(), "admins"); | |||
expectedException.expect(NotFoundException.class); | |||
userSession.login("admin").setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam("id", group.getId().toString()) | |||
.setParam("login", "my-admin") | |||
@@ -182,17 +172,8 @@ public class RemoveUserActionTest { | |||
return ws.newPostRequest("api/user_groups", "remove_user"); | |||
} | |||
private GroupDto insertGroup(String groupName) { | |||
return groupDao.insert(dbSession, new GroupDto() | |||
.setName(groupName) | |||
.setDescription(StringUtils.capitalize(groupName))); | |||
} | |||
private UserDto insertUser(String login) { | |||
return userDao.insert(dbSession, new UserDto().setLogin(login).setName(login).setActive(true)); | |||
private void loginAsAdmin() { | |||
userSession.login("admin").setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); | |||
} | |||
private void insertMember(long groupId, long userId) { | |||
userGroupDao.insert(dbSession, new UserGroupDto().setGroupId(groupId).setUserId(userId)); | |||
} | |||
} |
@@ -19,27 +19,27 @@ | |||
*/ | |||
package org.sonar.server.usergroups.ws; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.junit.Before; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.ExpectedException; | |||
import org.sonar.api.server.ws.WebService.Param; | |||
import org.sonar.api.utils.System2; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.DbTester; | |||
import org.sonar.db.user.GroupDao; | |||
import org.sonar.db.user.UserGroupDao; | |||
import org.sonar.db.user.UserGroupDto; | |||
import org.sonar.db.organization.OrganizationDto; | |||
import org.sonar.db.organization.OrganizationTesting; | |||
import org.sonar.db.user.GroupDto; | |||
import org.sonar.db.user.UserDto; | |||
import org.sonar.server.exceptions.UnauthorizedException; | |||
import org.sonar.server.organization.DefaultOrganizationProviderRule; | |||
import org.sonar.server.tester.UserSessionRule; | |||
import org.sonar.server.ws.WsTester; | |||
import static org.apache.commons.lang.StringUtils.capitalize; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.sonar.db.organization.OrganizationTesting.newOrganizationDto; | |||
import static org.sonar.db.user.GroupTesting.newGroupDto; | |||
public class SearchActionTest { | |||
@Rule | |||
@@ -53,19 +53,9 @@ public class SearchActionTest { | |||
private WsTester ws; | |||
private GroupDao groupDao; | |||
private UserGroupDao userGroupDao; | |||
private DbSession dbSession; | |||
@Before | |||
public void setUp() { | |||
DbClient dbClient = db.getDbClient(); | |||
groupDao = dbClient.groupDao(); | |||
userGroupDao = dbClient.userGroupDao(); | |||
ws = new WsTester(new UserGroupsWs(new SearchAction(dbClient, userSession))); | |||
dbSession = dbClient.openSession(false); | |||
ws = new WsTester(new UserGroupsWs(new SearchAction(db.getDbClient(), userSession, newGroupWsSupport()))); | |||
} | |||
@Test | |||
@@ -76,40 +66,49 @@ public class SearchActionTest { | |||
@Test | |||
public void search_without_parameters() throws Exception { | |||
loginAsSimpleUser(); | |||
insertGroups("users", "admins", "customer1", "customer2", "customer3"); | |||
dbSession.commit(); | |||
insertGroup(db.getDefaultOrganization(), "users", 0); | |||
insertGroup(db.getDefaultOrganization(), "admins", 0); | |||
insertGroup(db.getDefaultOrganization(), "customer1", 0); | |||
insertGroup(db.getDefaultOrganization(), "customer2", 0); | |||
insertGroup(db.getDefaultOrganization(), "customer3", 0); | |||
loginAsSimpleUser(); | |||
newRequest().execute().assertJson(getClass(), "five_groups.json"); | |||
} | |||
@Test | |||
public void search_with_members() throws Exception { | |||
loginAsSimpleUser(); | |||
insertGroups("users", "admins", "customer1", "customer2", "customer3"); | |||
insertMembers("users", 5); | |||
insertMembers("admins", 1); | |||
insertMembers("customer2", 4); | |||
dbSession.commit(); | |||
insertGroup(db.getDefaultOrganization(), "users", 5); | |||
insertGroup(db.getDefaultOrganization(), "admins", 1); | |||
insertGroup(db.getDefaultOrganization(), "customer1", 0); | |||
insertGroup(db.getDefaultOrganization(), "customer2", 4); | |||
insertGroup(db.getDefaultOrganization(), "customer3", 0); | |||
loginAsSimpleUser(); | |||
newRequest().execute().assertJson(getClass(), "with_members.json"); | |||
} | |||
@Test | |||
public void search_with_query() throws Exception { | |||
loginAsSimpleUser(); | |||
insertGroups("users", "admins", "customer%_%/1", "customer%_%/2", "customer%_%/3"); | |||
dbSession.commit(); | |||
insertGroup(db.getDefaultOrganization(), "users", 0); | |||
insertGroup(db.getDefaultOrganization(), "admins", 0); | |||
insertGroup(db.getDefaultOrganization(), "customer%_%/1", 0); | |||
insertGroup(db.getDefaultOrganization(), "customer%_%/2", 0); | |||
insertGroup(db.getDefaultOrganization(), "customer%_%/3", 0); | |||
loginAsSimpleUser(); | |||
newRequest().setParam(Param.TEXT_QUERY, "tomer%_%/").execute().assertJson(getClass(), "customers.json"); | |||
} | |||
@Test | |||
public void search_with_paging() throws Exception { | |||
loginAsSimpleUser(); | |||
insertGroups("users", "admins", "customer1", "customer2", "customer3"); | |||
dbSession.commit(); | |||
insertGroup(db.getDefaultOrganization(), "users", 0); | |||
insertGroup(db.getDefaultOrganization(), "admins", 0); | |||
insertGroup(db.getDefaultOrganization(), "customer1", 0); | |||
insertGroup(db.getDefaultOrganization(), "customer2", 0); | |||
insertGroup(db.getDefaultOrganization(), "customer3", 0); | |||
loginAsSimpleUser(); | |||
newRequest() | |||
.setParam(Param.PAGE_SIZE, "3").execute().assertJson(getClass(), "page_1.json"); | |||
newRequest() | |||
@@ -120,10 +119,9 @@ public class SearchActionTest { | |||
@Test | |||
public void search_with_fields() throws Exception { | |||
loginAsSimpleUser(); | |||
insertGroups("sonar-users"); | |||
dbSession.commit(); | |||
insertGroup(db.getDefaultOrganization(), "sonar-users", 0); | |||
loginAsSimpleUser(); | |||
assertThat(newRequest().execute().outputAsString()) | |||
.contains("id") | |||
.contains("name") | |||
@@ -156,7 +154,23 @@ public class SearchActionTest { | |||
} | |||
@Test | |||
public void fail_when_not_logged() throws Exception { | |||
public void search_in_organization() throws Exception { | |||
OrganizationDto org = OrganizationTesting.insert(db, newOrganizationDto()); | |||
GroupDto group = db.users().insertGroup(org, "users"); | |||
// the group in default org is not returned | |||
db.users().insertGroup(db.getDefaultOrganization(), "users"); | |||
loginAsSimpleUser(); | |||
newRequest() | |||
.setParam("organization", org.getKey()) | |||
.execute() | |||
.assertJson( | |||
"{\"total\":1,\"p\":1,\"ps\":100," + | |||
"\"groups\":[{\"id\":\"" + group.getId() + "\",\"name\":\"users\"}]}\n"); | |||
} | |||
@Test | |||
public void fail_when_not_logged_in() throws Exception { | |||
userSession.anonymous(); | |||
expectedException.expect(UnauthorizedException.class); | |||
@@ -167,18 +181,12 @@ public class SearchActionTest { | |||
return ws.newGetRequest("api/user_groups", "search"); | |||
} | |||
private void insertGroups(String... groupNames) { | |||
for (String groupName : groupNames) { | |||
groupDao.insert(dbSession, newGroupDto() | |||
.setName(groupName) | |||
.setDescription(StringUtils.capitalize(groupName))); | |||
} | |||
} | |||
private void insertMembers(String groupName, int count) { | |||
long groupId = groupDao.selectOrFailByName(dbSession, groupName).getId(); | |||
for (int i = 0; i < count; i++) { | |||
userGroupDao.insert(dbSession, new UserGroupDto().setGroupId(groupId).setUserId((long) i + 1)); | |||
private void insertGroup(OrganizationDto org, String name, int numberOfMembers) { | |||
GroupDto group = newGroupDto().setName(name).setDescription(capitalize(name)).setOrganizationUuid(org.getUuid()); | |||
db.users().insertGroup(group); | |||
for (int i = 0; i < numberOfMembers; i++) { | |||
UserDto user = db.users().insertUser(); | |||
db.users().insertMember(group, user); | |||
} | |||
} | |||
@@ -186,4 +194,8 @@ public class SearchActionTest { | |||
userSession.login("user"); | |||
} | |||
private GroupWsSupport newGroupWsSupport() { | |||
return new GroupWsSupport(db.getDbClient(), DefaultOrganizationProviderRule.create(db)); | |||
} | |||
} |
@@ -19,7 +19,6 @@ | |||
*/ | |||
package org.sonar.server.usergroups.ws; | |||
import java.net.HttpURLConnection; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.junit.Before; | |||
import org.junit.Rule; | |||
@@ -27,16 +26,16 @@ import org.junit.Test; | |||
import org.junit.rules.ExpectedException; | |||
import org.sonar.api.utils.System2; | |||
import org.sonar.core.permission.GlobalPermissions; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.DbTester; | |||
import org.sonar.db.user.GroupDao; | |||
import org.sonar.db.organization.OrganizationDto; | |||
import org.sonar.db.organization.OrganizationTesting; | |||
import org.sonar.db.user.GroupDto; | |||
import org.sonar.db.user.UserGroupDao; | |||
import org.sonar.db.user.UserGroupDto; | |||
import org.sonar.db.user.UserDto; | |||
import org.sonar.server.exceptions.ForbiddenException; | |||
import org.sonar.server.exceptions.NotFoundException; | |||
import org.sonar.server.exceptions.ServerException; | |||
import org.sonar.server.organization.DefaultOrganizationProviderRule; | |||
import org.sonar.server.platform.PersistentSettings; | |||
import org.sonar.server.tester.UserSessionRule; | |||
import org.sonar.server.ws.WsTester; | |||
@@ -47,42 +46,40 @@ import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.never; | |||
import static org.mockito.Mockito.verify; | |||
import static org.mockito.Mockito.when; | |||
import static org.sonar.db.organization.OrganizationTesting.newOrganizationDto; | |||
public class UpdateActionTest { | |||
static final String DEFAULT_GROUP_NAME_KEY = "sonar.defaultGroup"; | |||
static final String DEFAULT_GROUP_NAME_VALUE = "DEFAULT_GROUP_NAME_VALUE"; | |||
private static final String DEFAULT_GROUP_NAME_KEY = "sonar.defaultGroup"; | |||
private static final String DEFAULT_GROUP_NAME_VALUE = "DEFAULT_GROUP_NAME_VALUE"; | |||
@Rule | |||
public DbTester db = DbTester.create(System2.INSTANCE); | |||
@Rule | |||
public UserSessionRule userSession = UserSessionRule.standalone(); | |||
@Rule | |||
public ExpectedException expectedException = ExpectedException.none(); | |||
DbClient dbClient = db.getDbClient(); | |||
DbSession dbSession = db.getSession(); | |||
GroupDao groupDao = dbClient.groupDao(); | |||
UserGroupDao userGroupDao = dbClient.userGroupDao(); | |||
PersistentSettings settings = mock(PersistentSettings.class); | |||
WsTester ws = new WsTester(new UserGroupsWs(new UpdateAction(dbClient, userSession, new UserGroupUpdater(dbClient), settings))); | |||
private DefaultOrganizationProviderRule defaultOrganizationProvider = DefaultOrganizationProviderRule.create(db); | |||
private PersistentSettings settings = mock(PersistentSettings.class); | |||
private WsTester ws = new WsTester(new UserGroupsWs(new UpdateAction(db.getDbClient(), userSession, new GroupWsSupport(db.getDbClient(), defaultOrganizationProvider), settings, defaultOrganizationProvider))); | |||
@Before | |||
public void setUp() throws Exception { | |||
GroupWsSupport groupSupport = new GroupWsSupport(db.getDbClient(), defaultOrganizationProvider); | |||
ws = new WsTester(new UserGroupsWs(new UpdateAction(db.getDbClient(), userSession, groupSupport, settings, defaultOrganizationProvider))); | |||
when(settings.getString(DEFAULT_GROUP_NAME_KEY)).thenReturn(DEFAULT_GROUP_NAME_VALUE); | |||
} | |||
@Test | |||
public void update_nominal() throws Exception { | |||
GroupDto existingGroup = groupDao.insert(dbSession, new GroupDto().setName("old-name").setDescription("Old Description")); | |||
userGroupDao.insert(dbSession, new UserGroupDto().setGroupId(existingGroup.getId()).setUserId(42L)); | |||
dbSession.commit(); | |||
public void update_both_name_and_description() throws Exception { | |||
GroupDto group = db.users().insertGroup(defaultOrganizationProvider.getDto(), "Initial Name"); | |||
UserDto user = db.users().insertUser(); | |||
db.users().insertMember(group, user); | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam("id", existingGroup.getId().toString()) | |||
.setParam("id", group.getId().toString()) | |||
.setParam("name", "new-name") | |||
.setParam("description", "New Description") | |||
.execute().assertJson("{" + | |||
@@ -96,17 +93,16 @@ public class UpdateActionTest { | |||
@Test | |||
public void update_only_name() throws Exception { | |||
GroupDto existingGroup = groupDao.insert(dbSession, new GroupDto().setName("old-name").setDescription("Old Description")); | |||
dbSession.commit(); | |||
GroupDto group = db.users().insertGroup(defaultOrganizationProvider.getDto(), "Initial Name"); | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam("id", existingGroup.getId().toString()) | |||
.setParam("id", group.getId().toString()) | |||
.setParam("name", "new-name") | |||
.execute().assertJson("{" + | |||
" \"group\": {" + | |||
" \"name\": \"new-name\"," + | |||
" \"description\": \"Old Description\"," + | |||
" \"description\": \"" + group.getDescription() + "\"," + | |||
" \"membersCount\": 0" + | |||
" }" + | |||
"}"); | |||
@@ -114,16 +110,15 @@ public class UpdateActionTest { | |||
@Test | |||
public void update_only_description() throws Exception { | |||
GroupDto existingGroup = groupDao.insert(dbSession, new GroupDto().setName("old-name").setDescription("Old Description")); | |||
dbSession.commit(); | |||
GroupDto group = db.users().insertGroup(defaultOrganizationProvider.getDto(), "Initial Name"); | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam("id", existingGroup.getId().toString()) | |||
.setParam("id", group.getId().toString()) | |||
.setParam("description", "New Description") | |||
.execute().assertJson("{" + | |||
" \"group\": {" + | |||
" \"name\": \"old-name\"," + | |||
" \"name\": \"" + group.getName() + "\"," + | |||
" \"description\": \"New Description\"," + | |||
" \"membersCount\": 0" + | |||
" }" + | |||
@@ -132,12 +127,11 @@ public class UpdateActionTest { | |||
@Test | |||
public void update_default_group_name_also_update_default_group_property() throws Exception { | |||
GroupDto existingGroup = groupDao.insert(dbSession, new GroupDto().setName(DEFAULT_GROUP_NAME_VALUE).setDescription("Default group name")); | |||
dbSession.commit(); | |||
GroupDto group = db.users().insertGroup(defaultOrganizationProvider.getDto(), DEFAULT_GROUP_NAME_VALUE); | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam("id", existingGroup.getId().toString()) | |||
.setParam("id", group.getId().toString()) | |||
.setParam("name", "new-name") | |||
.execute(); | |||
@@ -147,12 +141,27 @@ public class UpdateActionTest { | |||
@Test | |||
public void update_default_group_name_does_not_update_default_group_setting_when_null() throws Exception { | |||
when(settings.getString(DEFAULT_GROUP_NAME_KEY)).thenReturn(null); | |||
GroupDto existingGroup = groupDao.insert(dbSession, new GroupDto().setName(DEFAULT_GROUP_NAME_VALUE).setDescription("Default group name")); | |||
dbSession.commit(); | |||
GroupDto group = db.users().insertGroup(defaultOrganizationProvider.getDto(), DEFAULT_GROUP_NAME_VALUE); | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam("id", group.getId().toString()) | |||
.setParam("name", "new-name") | |||
.execute(); | |||
verify(settings, never()).saveProperty(any(DbSession.class), eq(DEFAULT_GROUP_NAME_KEY), eq("new-name")); | |||
} | |||
@Test | |||
public void do_not_update_default_group_of_default_organization_if_updating_group_on_non_default_organization() throws Exception { | |||
OrganizationDto org = OrganizationTesting.insert(db, newOrganizationDto()); | |||
when(settings.getString(DEFAULT_GROUP_NAME_KEY)).thenReturn(DEFAULT_GROUP_NAME_VALUE); | |||
GroupDto groupInDefaultOrg = db.users().insertGroup(defaultOrganizationProvider.getDto(), DEFAULT_GROUP_NAME_VALUE); | |||
GroupDto group = db.users().insertGroup(org, DEFAULT_GROUP_NAME_VALUE); | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam("id", existingGroup.getId().toString()) | |||
.setParam("id", group.getId().toString()) | |||
.setParam("name", "new-name") | |||
.execute(); | |||
@@ -161,9 +170,10 @@ public class UpdateActionTest { | |||
@Test | |||
public void require_admin_permission() throws Exception { | |||
userSession.login("not-admin"); | |||
expectedException.expect(ForbiddenException.class); | |||
userSession.login("not-admin"); | |||
newRequest() | |||
.setParam("id", "42") | |||
.setParam("name", "some-product-bu") | |||
@@ -172,85 +182,86 @@ public class UpdateActionTest { | |||
} | |||
@Test | |||
public void name_too_short() throws Exception { | |||
GroupDto existingGroup = groupDao.insert(dbSession, new GroupDto().setName("old-name").setDescription("Old Description")); | |||
dbSession.commit(); | |||
public void fail_if_name_is_too_short() throws Exception { | |||
GroupDto group = db.users().insertGroup(defaultOrganizationProvider.getDto(), "a name"); | |||
loginAsAdmin(); | |||
expectedException.expect(IllegalArgumentException.class); | |||
expectedException.expectMessage("Group name cannot be empty"); | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam("id", existingGroup.getId().toString()) | |||
.setParam("id", group.getId().toString()) | |||
.setParam("name", "") | |||
.execute(); | |||
} | |||
@Test | |||
public void name_too_long() throws Exception { | |||
GroupDto existingGroup = groupDao.insert(dbSession, new GroupDto().setName("old-name").setDescription("Old Description")); | |||
dbSession.commit(); | |||
public void fail_if_name_is_too_long() throws Exception { | |||
GroupDto group = db.users().insertGroup(defaultOrganizationProvider.getDto(), "a name"); | |||
loginAsAdmin(); | |||
expectedException.expect(IllegalArgumentException.class); | |||
expectedException.expectMessage("Group name cannot be longer than 255 characters"); | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam("id", existingGroup.getId().toString()) | |||
.setParam("id", group.getId().toString()) | |||
.setParam("name", StringUtils.repeat("a", 255 + 1)) | |||
.execute(); | |||
} | |||
@Test | |||
public void forbidden_name() throws Exception { | |||
GroupDto existingGroup = groupDao.insert(dbSession, new GroupDto().setName("old-name").setDescription("Old Description")); | |||
dbSession.commit(); | |||
public void fail_if_new_name_is_anyone() throws Exception { | |||
GroupDto group = db.users().insertGroup(defaultOrganizationProvider.getDto(), "a name"); | |||
loginAsAdmin(); | |||
expectedException.expect(IllegalArgumentException.class); | |||
expectedException.expectMessage("Anyone group cannot be used"); | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam("id", existingGroup.getId().toString()) | |||
.setParam("id", group.getId().toString()) | |||
.setParam("name", "AnYoNe") | |||
.execute(); | |||
} | |||
@Test | |||
public void non_unique_name() throws Exception { | |||
GroupDto existingGroup = groupDao.insert(dbSession, new GroupDto().setName("old-name").setDescription("Old Description")); | |||
String groupName = "conflicting-name"; | |||
groupDao.insert(dbSession, new GroupDto() | |||
.setName(groupName)); | |||
dbSession.commit(); | |||
public void fail_to_update_if_name_already_exists() throws Exception { | |||
OrganizationDto defaultOrg = defaultOrganizationProvider.getDto(); | |||
GroupDto groupToBeRenamed = db.users().insertGroup(defaultOrg, "a name"); | |||
String newName = "new-name"; | |||
db.users().insertGroup(defaultOrg, newName); | |||
loginAsAdmin(); | |||
expectedException.expect(ServerException.class); | |||
expectedException.expectMessage("already taken"); | |||
expectedException.expectMessage("Group 'new-name' already exists"); | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam("id", existingGroup.getId().toString()) | |||
.setParam("name", groupName) | |||
.execute().assertStatus(HttpURLConnection.HTTP_CONFLICT); | |||
.setParam("id", groupToBeRenamed.getId().toString()) | |||
.setParam("name", newName) | |||
.execute(); | |||
} | |||
@Test | |||
public void description_too_long() throws Exception { | |||
GroupDto existingGroup = groupDao.insert(dbSession, new GroupDto().setName("old-name").setDescription("Old Description")); | |||
dbSession.commit(); | |||
public void fail_if_description_is_too_long() throws Exception { | |||
GroupDto group = db.users().insertGroup(defaultOrganizationProvider.getDto(), "a name"); | |||
loginAsAdmin(); | |||
expectedException.expect(IllegalArgumentException.class); | |||
expectedException.expectMessage("Description cannot be longer than 200 characters"); | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam("id", existingGroup.getId().toString()) | |||
.setParam("id", group.getId().toString()) | |||
.setParam("name", "long-group-description-is-looooooooooooong") | |||
.setParam("description", StringUtils.repeat("a", 200 + 1)) | |||
.setParam("description", StringUtils.repeat("a", 201)) | |||
.execute(); | |||
} | |||
@Test | |||
public void unknown_group() throws Exception { | |||
public void fail_if_unknown_group() throws Exception { | |||
loginAsAdmin(); | |||
expectedException.expect(NotFoundException.class); | |||
expectedException.expectMessage("Could not find a user group with id '42'."); | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam("id", "42") | |||
.execute(); | |||
@@ -263,6 +274,4 @@ public class UpdateActionTest { | |||
private void loginAsAdmin() { | |||
userSession.login("admin").setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); | |||
} | |||
} |
@@ -29,6 +29,6 @@ public class UserGroupsModuleTest { | |||
public void verify_count_of_added_components() { | |||
ComponentContainer container = new ComponentContainer(); | |||
new UserGroupsModule().configure(container); | |||
assertThat(container.size()).isEqualTo(12); | |||
assertThat(container.size()).isEqualTo(11); | |||
} | |||
} |
@@ -40,9 +40,10 @@ public class UserGroupsWsTest { | |||
@Before | |||
public void setUp() { | |||
GroupWsSupport wsSupport = mock(GroupWsSupport.class); | |||
WsTester tester = new WsTester(new UserGroupsWs( | |||
new SearchAction(mock(DbClient.class), mock(UserSession.class)), | |||
new CreateAction(mock(DbClient.class), mock(UserSession.class), mock(UserGroupUpdater.class)))); | |||
new SearchAction(mock(DbClient.class), mock(UserSession.class), wsSupport), | |||
new CreateAction(mock(DbClient.class), mock(UserSession.class), wsSupport))); | |||
controller = tester.controller("api/user_groups"); | |||
} | |||
@@ -59,7 +60,7 @@ public class UserGroupsWsTest { | |||
WebService.Action action = controller.action("search"); | |||
assertThat(action).isNotNull(); | |||
assertThat(action.responseExampleAsString()).isNotEmpty(); | |||
assertThat(action.params()).hasSize(4); | |||
assertThat(action.params()).hasSize(5); | |||
} | |||
@Test | |||
@@ -68,6 +69,6 @@ public class UserGroupsWsTest { | |||
assertThat(action).isNotNull(); | |||
assertThat(action.isPost()).isTrue(); | |||
assertThat(action.responseExampleAsString()).isNotEmpty(); | |||
assertThat(action.params()).hasSize(2); | |||
assertThat(action.params()).hasSize(3); | |||
} | |||
} |
@@ -26,21 +26,19 @@ import org.sonar.api.server.ws.WebService.Param; | |||
import org.sonar.api.server.ws.WebService.SelectionMode; | |||
import org.sonar.api.utils.System2; | |||
import org.sonar.core.permission.GlobalPermissions; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.DbTester; | |||
import org.sonar.db.user.GroupDto; | |||
import org.sonar.db.user.UserDto; | |||
import org.sonar.db.user.UserGroupDto; | |||
import org.sonar.server.exceptions.ForbiddenException; | |||
import org.sonar.server.exceptions.NotFoundException; | |||
import org.sonar.server.organization.DefaultOrganizationProviderRule; | |||
import org.sonar.server.tester.UserSessionRule; | |||
import org.sonar.server.ws.WsTester; | |||
import org.sonar.server.ws.WsTester.TestRequest; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.sonar.server.usergroups.ws.UserGroupsWsParameters.PARAM_GROUP_NAME; | |||
import static org.sonar.db.user.UserTesting.newUserDto; | |||
import static org.sonar.server.usergroups.ws.GroupWsSupport.PARAM_GROUP_NAME; | |||
public class UsersActionTest { | |||
@@ -48,34 +46,30 @@ public class UsersActionTest { | |||
public DbTester db = DbTester.create(System2.INSTANCE); | |||
@Rule | |||
public UserSessionRule userSession = UserSessionRule.standalone(); | |||
WsTester wsTester; | |||
DbClient dbClient; | |||
DbSession dbSession; | |||
private DefaultOrganizationProviderRule defaultOrganizationProvider = DefaultOrganizationProviderRule.create(db); | |||
private WsTester wsTester; | |||
@Before | |||
public void setUp() { | |||
dbClient = db.getDbClient(); | |||
dbSession = db.getSession(); | |||
GroupWsSupport groupSupport = new GroupWsSupport(db.getDbClient(), defaultOrganizationProvider); | |||
wsTester = new WsTester(new UserGroupsWs( | |||
new UsersAction( | |||
dbClient, | |||
new UserGroupFinder(dbClient), | |||
userSession))); | |||
db.getDbClient(), | |||
userSession, | |||
groupSupport))); | |||
userSession.login("admin").setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); | |||
} | |||
@Test(expected = NotFoundException.class) | |||
public void fail_on_unknown_user() throws Exception { | |||
public void fail_if_unknown_user() throws Exception { | |||
newUsersRequest() | |||
.setParam("id", "42") | |||
.setParam("login", "john").execute(); | |||
} | |||
@Test(expected = ForbiddenException.class) | |||
public void fail_on_missing_permission() throws Exception { | |||
public void fail_if_missing_permission() throws Exception { | |||
userSession.login("not-admin"); | |||
newUsersRequest() | |||
.setParam("id", "42") | |||
@@ -84,8 +78,7 @@ public class UsersActionTest { | |||
@Test | |||
public void empty_users() throws Exception { | |||
GroupDto group = insertGroup(); | |||
dbSession.commit(); | |||
GroupDto group = db.users().insertGroup(defaultOrganizationProvider.getDto(), "a group"); | |||
newUsersRequest() | |||
.setParam("login", "john") | |||
@@ -96,11 +89,10 @@ public class UsersActionTest { | |||
@Test | |||
public void all_users() throws Exception { | |||
GroupDto group = insertGroup(); | |||
UserDto groupUser = insertUser("ada", "Ada Lovelace"); | |||
insertUser("grace", "Grace Hopper"); | |||
addUserToGroup(groupUser, group); | |||
dbSession.commit(); | |||
GroupDto group = db.users().insertGroup(defaultOrganizationProvider.getDto(), "a group"); | |||
UserDto user1 = db.users().insertUser(newUserDto().setLogin("ada").setName("Ada Lovelace")); | |||
db.users().insertMember(group, user1); | |||
db.users().insertUser(newUserDto().setLogin("grace").setName("Grace Hopper")); | |||
newUsersRequest() | |||
.setParam("id", group.getId().toString()) | |||
@@ -111,12 +103,11 @@ public class UsersActionTest { | |||
@Test | |||
public void all_users_by_group_name() throws Exception { | |||
GroupDto group = insertGroup(); | |||
UserDto adaLovelace = insertUser("ada", "Ada Lovelace"); | |||
UserDto graceHopper = insertUser("grace", "Grace Hopper"); | |||
addUserToGroup(adaLovelace, group); | |||
addUserToGroup(graceHopper, group); | |||
dbSession.commit(); | |||
GroupDto group = db.users().insertGroup(defaultOrganizationProvider.getDto(), "a group"); | |||
UserDto adaLovelace = db.users().insertUser(newUserDto().setLogin("ada").setName("Ada Lovelace")); | |||
UserDto graceHopper = db.users().insertUser(newUserDto().setLogin("grace").setName("Grace Hopper")); | |||
db.users().insertMember(group, adaLovelace); | |||
db.users().insertMember(group, graceHopper); | |||
String response = newUsersRequest() | |||
.setParam(PARAM_GROUP_NAME, group.getName()) | |||
@@ -127,11 +118,10 @@ public class UsersActionTest { | |||
@Test | |||
public void selected_users() throws Exception { | |||
GroupDto group = insertGroup(); | |||
UserDto groupUser = insertUser("ada", "Ada Lovelace"); | |||
insertUser("grace", "Grace Hopper"); | |||
addUserToGroup(groupUser, group); | |||
dbSession.commit(); | |||
GroupDto group = db.users().insertGroup(defaultOrganizationProvider.getDto(), "a group"); | |||
UserDto user1 = db.users().insertUser(newUserDto().setLogin("ada").setName("Ada Lovelace")); | |||
db.users().insertUser(newUserDto().setLogin("grace").setName("Grace Hopper")); | |||
db.users().insertMember(group, user1); | |||
newUsersRequest() | |||
.setParam("id", group.getId().toString()) | |||
@@ -147,11 +137,10 @@ public class UsersActionTest { | |||
@Test | |||
public void deselected_users() throws Exception { | |||
GroupDto group = insertGroup(); | |||
UserDto groupUser = insertUser("ada", "Ada Lovelace"); | |||
insertUser("grace", "Grace Hopper"); | |||
addUserToGroup(groupUser, group); | |||
dbSession.commit(); | |||
GroupDto group = db.users().insertGroup(defaultOrganizationProvider.getDto(), "a group"); | |||
UserDto user1 = db.users().insertUser(newUserDto().setLogin("ada").setName("Ada Lovelace")); | |||
db.users().insertUser(newUserDto().setLogin("grace").setName("Grace Hopper")); | |||
db.users().insertMember(group, user1); | |||
newUsersRequest() | |||
.setParam("id", group.getId().toString()) | |||
@@ -162,11 +151,10 @@ public class UsersActionTest { | |||
@Test | |||
public void paging() throws Exception { | |||
GroupDto group = insertGroup(); | |||
UserDto groupUser = insertUser("ada", "Ada Lovelace"); | |||
insertUser("grace", "Grace Hopper"); | |||
addUserToGroup(groupUser, group); | |||
dbSession.commit(); | |||
GroupDto group = db.users().insertGroup(defaultOrganizationProvider.getDto(), "a group"); | |||
UserDto user1 = db.users().insertUser(newUserDto().setLogin("ada").setName("Ada Lovelace")); | |||
db.users().insertUser(newUserDto().setLogin("grace").setName("Grace Hopper")); | |||
db.users().insertMember(group, user1); | |||
newUsersRequest() | |||
.setParam("id", group.getId().toString()) | |||
@@ -186,11 +174,10 @@ public class UsersActionTest { | |||
@Test | |||
public void filtering() throws Exception { | |||
GroupDto group = insertGroup(); | |||
UserDto groupUser = insertUser("ada", "Ada Lovelace"); | |||
insertUser("grace", "Grace Hopper"); | |||
addUserToGroup(groupUser, group); | |||
dbSession.commit(); | |||
GroupDto group = db.users().insertGroup(defaultOrganizationProvider.getDto(), "a group"); | |||
UserDto user1 = db.users().insertUser(newUserDto().setLogin("ada").setName("Ada Lovelace")); | |||
db.users().insertUser(newUserDto().setLogin("grace").setName("Grace Hopper")); | |||
db.users().insertMember(group, user1); | |||
newUsersRequest() | |||
.setParam("id", group.getId().toString()) | |||
@@ -210,16 +197,4 @@ public class UsersActionTest { | |||
return wsTester.newGetRequest("api/user_groups", "users"); | |||
} | |||
private GroupDto insertGroup() { | |||
return dbClient.groupDao().insert(dbSession, new GroupDto() | |||
.setName("sonar-users")); | |||
} | |||
private UserDto insertUser(String login, String name) { | |||
return dbClient.userDao().insert(dbSession, new UserDto().setLogin(login).setName(name)); | |||
} | |||
private void addUserToGroup(UserDto user, GroupDto usersGroup) { | |||
dbClient.userGroupDao().insert(dbSession, new UserGroupDto().setUserId(user.getId()).setGroupId(usersGroup.getId())); | |||
} | |||
} |
@@ -18,7 +18,8 @@ | |||
name="sonar-devs" | |||
description="Sonar Devs" | |||
created_at="2014-09-08" | |||
updated_at="2014-09-08"/> | |||
updated_at="2014-09-08" | |||
organization_uuid="org1"/> | |||
<groups_users user_id="101" | |||
group_id="1"/> |
@@ -18,7 +18,8 @@ | |||
name="sonar-users" | |||
description="Sonar Users" | |||
created_at="2014-09-08" | |||
updated_at="2014-09-08"/> | |||
updated_at="2014-09-08" | |||
organization_uuid="org1"/> | |||
<groups_users user_id="101" | |||
group_id="1"/> |
@@ -30,7 +30,7 @@ import org.sonar.db.MyBatis; | |||
public class DatabaseVersion { | |||
public static final int LAST_VERSION = 1_413; | |||
public static final int LAST_VERSION = 1_414; | |||
/** | |||
* The minimum supported version which can be upgraded. Lower |
@@ -502,6 +502,7 @@ INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1410'); | |||
INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1411'); | |||
INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1412'); | |||
INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1413'); | |||
INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1414'); | |||
INSERT INTO USERS(ID, LOGIN, NAME, EMAIL, EXTERNAL_IDENTITY, EXTERNAL_IDENTITY_PROVIDER, USER_LOCAL, CRYPTED_PASSWORD, SALT, IS_ROOT, CREATED_AT, UPDATED_AT) VALUES (1, 'admin', 'Administrator', '', 'admin', 'sonarqube', true, 'a373a0e667abb2604c1fd571eb4ad47fe8cc0878', '48bc4b0d93179b5103fd3885ea9119498e9d161b', true, '1418215735482', '1418215735482'); | |||
ALTER TABLE USERS ALTER COLUMN ID RESTART WITH 2; |
@@ -39,6 +39,7 @@ import org.sonar.db.issue.IssueFilterDto; | |||
import org.sonar.db.issue.IssueFilterFavouriteDto; | |||
import org.sonar.db.measure.MeasureFilterDto; | |||
import org.sonar.db.measure.MeasureFilterFavouriteDto; | |||
import org.sonar.db.permission.UserPermissionDto; | |||
import org.sonar.db.property.PropertyDto; | |||
import org.sonar.db.property.PropertyQuery; | |||
@@ -50,6 +51,7 @@ import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.when; | |||
import static org.sonar.db.user.GroupMembershipQuery.IN; | |||
import static org.sonar.db.user.GroupMembershipQuery.builder; | |||
import static org.sonar.db.user.GroupTesting.newGroupDto; | |||
import static org.sonar.db.user.UserTesting.newUserDto; | |||
public class UserDaoTest { | |||
@@ -722,13 +724,13 @@ public class UserDaoTest { | |||
private org.sonar.db.permission.UserPermissionDto insertUserPermission(UserDto user) { | |||
String permission = randomAlphanumeric(64); | |||
org.sonar.db.permission.UserPermissionDto dto = new org.sonar.db.permission.UserPermissionDto(permission, user.getId(), null); | |||
UserPermissionDto dto = new UserPermissionDto(db.getDefaultOrganization().getUuid(), permission, user.getId(), null); | |||
dbClient.userPermissionDao().insert(session, dto); | |||
return dto; | |||
} | |||
private UserGroupDto insertUserGroup(UserDto user) { | |||
GroupDto group = new GroupDto().setName(randomAlphanumeric(30)); | |||
GroupDto group = newGroupDto().setName(randomAlphanumeric(30)); | |||
dbClient.groupDao().insert(session, group); | |||
UserGroupDto dto = new UserGroupDto().setUserId(user.getId()).setGroupId(group.getId()); |
@@ -29,6 +29,6 @@ public class MigrationStepModuleTest { | |||
public void verify_count_of_added_MigrationStep_types() { | |||
ComponentContainer container = new ComponentContainer(); | |||
new MigrationStepModule().configure(container); | |||
assertThat(container.size()).isEqualTo(153); | |||
assertThat(container.size()).isEqualTo(156); | |||
} | |||
} |
@@ -7,7 +7,8 @@ | |||
<user_roles id="1" | |||
user_id="10" | |||
resource_id="[null]" | |||
role="user"/> | |||
role="user" | |||
organization_uuid="org1"/> | |||
<groups_users user_id="10" | |||
group_id="[null]"/> |
@@ -12,11 +12,13 @@ | |||
<user_roles id="1" | |||
user_id="999" | |||
resource_id="[null]" | |||
role="user"/> | |||
role="user" | |||
organization_uuid="org1"/> | |||
<user_roles id="2" | |||
user_id="999" | |||
resource_id="[null]" | |||
role="user"/> | |||
role="user" | |||
organization_uuid="org1"/> | |||
<groups_users user_id="10" | |||
group_id="200"/> |
@@ -12,15 +12,18 @@ | |||
<user_roles id="1" | |||
user_id="10" | |||
resource_id="[null]" | |||
role="user"/> | |||
role="user" | |||
organization_uuid="org1"/> | |||
<user_roles id="2" | |||
user_id="10" | |||
resource_id="[null]" | |||
role="admin"/> | |||
role="admin" | |||
organization_uuid="org1"/> | |||
<user_roles id="3" | |||
user_id="11" | |||
resource_id="[null]" | |||
role="user"/> | |||
role="user" | |||
organization_uuid="org1"/> | |||
<groups_users user_id="999" | |||
group_id="200"/> |
@@ -1,9 +1,11 @@ | |||
<dataset> | |||
<groups id="100" | |||
name="sonar-administrators"/> | |||
name="sonar-administrators" | |||
organization_uuid="org1"/> | |||
<groups id="101" | |||
name="sonar-users"/> | |||
name="sonar-users" | |||
organization_uuid="org1"/> | |||
<users id="200" | |||
login="marius" | |||
@@ -30,7 +32,8 @@ | |||
<user_roles id="1" | |||
user_id="200" | |||
resource_id="1" | |||
role="admin"/> | |||
role="admin" | |||
organization_uuid="org1"/> | |||
<!-- new groups permissions : sonar-administrators (admin), sonar-users (user & codeviewer), Anyone (user & codeviewer) --> | |||
<group_roles id="3" | |||
@@ -62,20 +65,24 @@ | |||
<user_roles id="2" | |||
user_id="200" | |||
resource_id="123" | |||
role="admin"/> | |||
role="admin" | |||
organization_uuid="org1"/> | |||
<user_roles id="3" | |||
user_id="201" | |||
resource_id="123" | |||
role="admin"/> | |||
role="admin" | |||
organization_uuid="org1"/> | |||
<user_roles id="4" | |||
user_id="201" | |||
resource_id="123" | |||
role="user"/> | |||
role="user" | |||
organization_uuid="org1"/> | |||
<!-- default permission template for all qualifiers --> | |||
<permission_templates id="1" | |||
name="default" | |||
kee="default_20130101_010203"/> | |||
kee="default_20130101_010203" | |||
organization_uuid="org1"/> | |||
<perm_templates_groups id="1" | |||
template_id="1" |
@@ -1,9 +1,11 @@ | |||
<dataset> | |||
<groups id="100" | |||
name="sonar-administrators"/> | |||
name="sonar-administrators" | |||
organization_uuid="org1"/> | |||
<groups id="101" | |||
name="sonar-users"/> | |||
name="sonar-users" | |||
organization_uuid="org1"/> | |||
<users id="200" | |||
login="marius" | |||
@@ -30,7 +32,8 @@ | |||
<user_roles id="1" | |||
user_id="200" | |||
resource_id="1" | |||
role="admin"/> | |||
role="admin" | |||
organization_uuid="org1"/> | |||
<!-- new groups permissions : sonar-administrators (admin), sonar-users (user & codeviewer), Anyone (user & codeviewer) --> | |||
<group_roles id="3" | |||
@@ -62,12 +65,14 @@ | |||
<user_roles id="2" | |||
user_id="200" | |||
resource_id="123" | |||
role="admin"/> | |||
role="admin" | |||
organization_uuid="org1"/> | |||
<!-- default permission template for all qualifiers --> | |||
<permission_templates id="1" | |||
name="default" | |||
kee="default_20130101_010203"/> | |||
kee="default_20130101_010203" | |||
organization_uuid="org1"/> | |||
<perm_templates_groups id="1" | |||
template_id="1" |
@@ -1,9 +1,11 @@ | |||
<dataset> | |||
<groups id="100" | |||
name="sonar-administrators"/> | |||
name="sonar-administrators" | |||
organization_uuid="org1"/> | |||
<groups id="101" | |||
name="sonar-users"/> | |||
name="sonar-users" | |||
organization_uuid="org1"/> | |||
<users id="200" | |||
login="marius" | |||
@@ -24,7 +26,8 @@ | |||
<user_roles id="1" | |||
user_id="200" | |||
resource_id="1" | |||
role="admin"/> | |||
role="admin" | |||
organization_uuid="org1"/> | |||
<!-- new groups permissions : sonar-administrators (admin), sonar-users (user & codeviewer), Anyone (user & codeviewer) --> | |||
<group_roles id="3" | |||
@@ -56,12 +59,14 @@ | |||
<user_roles id="2" | |||
user_id="200" | |||
resource_id="123" | |||
role="admin"/> | |||
role="admin" | |||
organization_uuid="org1"/> | |||
<!-- default permission template for all qualifiers --> | |||
<permission_templates id="1" | |||
name="default" | |||
kee="default_20130101_010203"/> | |||
kee="default_20130101_010203" | |||
organization_uuid="org1"/> | |||
<perm_templates_groups id="1" | |||
template_id="1" |
@@ -8,12 +8,14 @@ | |||
is_root="[false]"/> | |||
<groups id="100" | |||
name="devs"/> | |||
name="devs" | |||
organization_uuid="org1"/> | |||
<user_roles id="1" | |||
user_id="200" | |||
resource_id="123" | |||
role="user"/> | |||
role="user" | |||
organization_uuid="org1"/> | |||
<group_roles id="1" | |||
group_id="100" |
@@ -8,7 +8,8 @@ | |||
is_root="[false]"/> | |||
<groups id="100" | |||
name="devs"/> | |||
name="devs" | |||
organization_uuid="org1"/> | |||
<user_roles/> | |||
@@ -8,12 +8,14 @@ | |||
is_root="[false]"/> | |||
<groups id="100" | |||
name="devs"/> | |||
name="devs" | |||
organization_uuid="org1"/> | |||
<user_roles id="1" | |||
user_id="200" | |||
resource_id="123" | |||
role="user"/> | |||
role="user" | |||
organization_uuid="org1"/> | |||
<group_roles id="1" | |||
group_id="100" |
@@ -4,7 +4,8 @@ | |||
kee="my_template_20130102_030405" | |||
description="my description" | |||
created_at="[null]" | |||
updated_at="[null]"/> | |||
updated_at="[null]" | |||
organization_uuid="org1"/> | |||
<users id="1" | |||
login="user1" |
@@ -4,7 +4,6 @@ | |||
kee="my_template_20130102_030405" | |||
description="my description" | |||
created_at="[null]" | |||
updated_at="[null]"/> | |||
updated_at="[null]" | |||
organization_uuid="org1"/> | |||
@@ -51,7 +50,6 @@ | |||
permission_reference="group_permission2"/> | |||
<groups id="1" | |||
name="group1"/> | |||
name="group1" | |||
organization_uuid="org1"/> | |||
<groups id="2" |
@@ -30,6 +30,7 @@ | |||
email="jo@hn.com" | |||
created_at="1418215735482" | |||
updated_at="1418215735482" | |||
active="[true]"/> | |||
active="[true]" | |||
is_root="[false]"/> | |||
</dataset> |
@@ -2,13 +2,16 @@ | |||
<groups id="100" | |||
name="sonar-administrators" | |||
description="System administrators"/> | |||
description="System administrators" | |||
organization_uuid="org1"/> | |||
<groups id="101" | |||
name="sonar-users" | |||
description="Any new users created will automatically join this group"/> | |||
description="Any new users created will automatically join this group" | |||
organization_uuid="org1"/> | |||
<groups id="102" | |||
name="sonar-reviewers" | |||
description="Reviewers"/> | |||
description="Reviewers" | |||
organization_uuid="org1"/> | |||
<!-- user 200 is in all groups --> | |||
<groups_users user_id="200" |
@@ -2,16 +2,20 @@ | |||
<groups id="100" | |||
name="sonar-administrators" | |||
description="System administrators"/> | |||
description="System administrators" | |||
organization_uuid="org1"/> | |||
<groups id="101" | |||
name="sonar-users" | |||
description="Any new users created will automatically join this group"/> | |||
description="Any new users created will automatically join this group" | |||
organization_uuid="org1"/> | |||
<groups id="102" | |||
name="sonar-reviewers" | |||
description="Reviewers"/> | |||
description="Reviewers" | |||
organization_uuid="org1"/> | |||
<groups id="103" | |||
name="sonar-nobody" | |||
description="Nobody in this group"/> | |||
description="Nobody in this group" | |||
organization_uuid="org1"/> | |||
<!-- user 200 is in all groups --> | |||
<groups_users user_id="200" |
@@ -8,12 +8,14 @@ | |||
is_root="[false]"/> | |||
<groups id="100" | |||
name="devs"/> | |||
name="devs" | |||
organization_uuid="org1"/> | |||
<user_roles id="1" | |||
user_id="200" | |||
resource_id="123" | |||
role="user"/> | |||
role="user" | |||
organization_uuid="org1"/> | |||
<group_roles id="1" | |||
group_id="100" |
@@ -8,7 +8,8 @@ | |||
is_root="[false]"/> | |||
<groups id="100" | |||
name="devs"/> | |||
name="devs" | |||
organization_uuid="org1"/> | |||
<user_roles/> | |||
@@ -8,12 +8,14 @@ | |||
is_root="[false]"/> | |||
<groups id="100" | |||
name="devs"/> | |||
name="devs" | |||
organization_uuid="org1"/> | |||
<user_roles id="1" | |||
user_id="200" | |||
resource_id="123" | |||
role="user"/> | |||
role="user" | |||
organization_uuid="org1"/> | |||
<group_roles id="1" | |||
group_id="100" |
@@ -1,8 +1,10 @@ | |||
<dataset> | |||
<groups id="100" | |||
name="sonar-administrators"/> | |||
name="sonar-administrators" | |||
organization_uuid="org1"/> | |||
<groups id="101" | |||
name="sonar-users"/> | |||
name="sonar-users" | |||
organization_uuid="org1"/> | |||
<users id="200" | |||
login="marius" | |||
name="Marius" | |||
@@ -21,7 +23,8 @@ | |||
<user_roles id="1" | |||
user_id="200" | |||
resource_id="123" | |||
role="codeviewer"/> | |||
role="codeviewer" | |||
organization_uuid="org1"/> | |||
<!-- other resource --> | |||
<group_roles id="3" | |||
@@ -31,6 +34,7 @@ | |||
<user_roles id="2" | |||
user_id="200" | |||
resource_id="999" | |||
role="codeviewer"/> | |||
role="codeviewer" | |||
organization_uuid="org1"/> | |||
</dataset> |
@@ -1,8 +1,10 @@ | |||
<dataset> | |||
<groups id="100" | |||
name="sonar-administrators"/> | |||
name="sonar-administrators" | |||
organization_uuid="org1"/> | |||
<groups id="101" | |||
name="sonar-users"/> | |||
name="sonar-users" | |||
organization_uuid="org1"/> | |||
<users id="200" | |||
login="marius" | |||
name="Marius" | |||
@@ -22,6 +24,7 @@ | |||
<user_roles id="2" | |||
user_id="200" | |||
resource_id="999" | |||
role="codeviewer"/> | |||
role="codeviewer" | |||
organization_uuid="org1"/> | |||
</dataset> |
@@ -1,8 +1,10 @@ | |||
<dataset> | |||
<groups id="100" | |||
name="sonar-administrators"/> | |||
name="sonar-administrators" | |||
organization_uuid="org1"/> | |||
<groups id="101" | |||
name="sonar-users"/> | |||
name="sonar-users" | |||
organization_uuid="org1"/> | |||
<users id="200" | |||
login="marius" | |||
name="Marius" | |||
@@ -21,7 +23,8 @@ | |||
<user_roles id="1" | |||
user_id="200" | |||
resource_id="123" | |||
role="codeviewer"/> | |||
role="codeviewer" | |||
organization_uuid="org1"/> | |||
<!-- other resource --> | |||
<group_roles id="3" | |||
@@ -31,6 +34,7 @@ | |||
<user_roles id="2" | |||
user_id="200" | |||
resource_id="999" | |||
role="codeviewer"/> | |||
role="codeviewer" | |||
organization_uuid="org1"/> | |||
</dataset> |
@@ -0,0 +1,43 @@ | |||
// SonarQube, open source software quality management tool. | |||
// Copyright (C) 2008-2015 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. | |||
syntax = "proto2"; | |||
package sonarqube.ws.usergroup; | |||
option java_package = "org.sonarqube.ws"; | |||
option java_outer_classname = "WsUserGroups"; | |||
option optimize_for = SPEED; | |||
// WS api/user_groups/create | |||
message CreateResponse { | |||
optional Group group = 1; | |||
} | |||
// WS api/user_groups/update | |||
message UpdateResponse { | |||
optional Group group = 1; | |||
} | |||
message Group { | |||
optional int64 id = 1; | |||
optional string organization = 2; | |||
optional string name = 3; | |||
optional string description = 4; | |||
optional int32 membersCount = 5; | |||
} |