aboutsummaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorSimon Brandhof <simon.brandhof@sonarsource.com>2016-10-12 18:53:31 +0200
committerSimon Brandhof <simon.brandhof@sonarsource.com>2016-10-13 12:13:11 +0200
commit73b71c9e8eb47c6d833cd5f4725be50719598b88 (patch)
treef21ba43e4888cddbf49d3b58db607206fba1183d /server
parent8595a520f31a9f2b0ea77e10086685d2290ac1f3 (diff)
downloadsonarqube-73b71c9e8eb47c6d833cd5f4725be50719598b88.tar.gz
sonarqube-73b71c9e8eb47c6d833cd5f4725be50719598b88.zip
Support organizations in user group web services
Diffstat (limited to 'server')
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/user/ws/GroupsAction.java11
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/AddUserAction.java45
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/CreateAction.java68
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/DeleteAction.java70
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/GroupId.java (renamed from server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/UserGroupFinder.java)47
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/GroupIdOrAnyone.java73
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/GroupWsRef.java163
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/GroupWsSupport.java195
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/RemoveUserAction.java68
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/SearchAction.java42
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/UpdateAction.java121
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/UserGroupUpdater.java74
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/UserGroupsModule.java3
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/UserGroupsWsParameters.java56
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/UsersAction.java25
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/WsGroupRef.java63
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/package-info.java1
-rw-r--r--server/sonar-server/src/main/resources/org/sonar/server/usergroups/ws/example-create.json1
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/user/ServerUserSessionTest.java49
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/AddUserActionTest.java172
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/CreateActionTest.java122
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/DeleteActionTest.java202
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/GroupWsRefTest.java89
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/RemoveUserActionTest.java145
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/SearchActionTest.java110
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/UpdateActionTest.java151
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/UserGroupsModuleTest.java2
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/UserGroupsWsTest.java9
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/UsersActionTest.java99
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/user/UserUpdaterTest/associate_default_groups_when_reactivating_user.xml3
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/user/UserUpdaterTest/not_associate_default_group_when_updating_user_if_already_existing.xml3
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1404_add_root_column_on_table_users.rb (renamed from server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1403_add_root_column_on_table_users.rb)0
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1405_populate_root_column_on_table_users.rb (renamed from server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1404_populate_root_column_on_table_users.rb)0
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1406_make_root_column_not_null_on_table_users.rb (renamed from server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1405_make_root_column_not_null_on_table_users.rb)0
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1407_populate_organization_uuid_of_groups.rb (renamed from server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1406_populate_organization_uuid_of_groups.rb)0
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1408_make_organization_uuid_not_null_on_groups.rb (renamed from server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1407_make_organization_uuid_not_null_on_groups.rb)0
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1409_add_organization_uuid_to_user_roles.rb (renamed from server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1408_add_organization_uuid_to_user_roles.rb)0
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1410_populate_organization_uuid_of_user_roles.rb (renamed from server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1409_populate_organization_uuid_of_user_roles.rb)0
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1411_make_organization_uuid_not_null_on_user_roles.rb (renamed from server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1410_make_organization_uuid_not_null_on_user_roles.rb)0
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1412_add_organization_uuid_to_permission_templates.rb (renamed from server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1411_add_organization_uuid_to_permission_templates.rb)0
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1413_populate_organization_uuid_of_permission_templates.rb (renamed from server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1412_populate_organization_uuid_of_permission_templates.rb)0
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1414_make_organization_uuid_not_null_on_permission_templates.rb (renamed from server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1413_make_organization_uuid_not_null_on_permission_templates.rb)0
42 files changed, 1341 insertions, 941 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/user/ws/GroupsAction.java b/server/sonar-server/src/main/java/org/sonar/server/user/ws/GroupsAction.java
index 6cd2552d378..5f486cb2edb 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/user/ws/GroupsAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/user/ws/GroupsAction.java
@@ -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();
}
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/AddUserAction.java b/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/AddUserAction.java
index 5200b7e935e..041219b42b8 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/AddUserAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/AddUserAction.java
@@ -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());
}
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/CreateAction.java b/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/CreateAction.java
index a043e4f73dc..f1884d31e12 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/CreateAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/CreateAction.java
@@ -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);
+ }
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/DeleteAction.java b/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/DeleteAction.java
index 829edb3a892..48c390a11d2 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/DeleteAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/DeleteAction.java
@@ -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());
}
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/UserGroupFinder.java b/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/GroupId.java
index 38b3cc3d94d..d9b4544a0ee 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/UserGroupFinder.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/GroupId.java
@@ -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());
}
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/GroupIdOrAnyone.java b/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/GroupIdOrAnyone.java
new file mode 100644
index 00000000000..ae782630882
--- /dev/null
+++ b/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/GroupIdOrAnyone.java
@@ -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);
+ }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/GroupWsRef.java b/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/GroupWsRef.java
new file mode 100644
index 00000000000..db97f15b15c
--- /dev/null
+++ b/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/GroupWsRef.java
@@ -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();
+ }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/GroupWsSupport.java b/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/GroupWsSupport.java
new file mode 100644
index 00000000000..d702b684ade
--- /dev/null
+++ b/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/GroupWsSupport.java
@@ -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");
+ }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/RemoveUserAction.java b/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/RemoveUserAction.java
index 63e1eb405f0..995961517dd 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/RemoveUserAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/RemoveUserAction.java
@@ -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) {
diff --git a/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/SearchAction.java b/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/SearchAction.java
index cc52587815c..e5deb2e92e2 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/SearchAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/SearchAction.java
@@ -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);
}
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/UpdateAction.java b/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/UpdateAction.java
index 76ea2367b20..22489e2090b 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/UpdateAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/UpdateAction.java
@@ -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);
+ }
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/UserGroupUpdater.java b/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/UserGroupUpdater.java
deleted file mode 100644
index de2e7bd5960..00000000000
--- a/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/UserGroupUpdater.java
+++ /dev/null
@@ -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();
- }
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/UserGroupsModule.java b/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/UserGroupsModule.java
index 68d24901aa3..acc032f76f1 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/UserGroupsModule.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/UserGroupsModule.java
@@ -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,
diff --git a/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/UserGroupsWsParameters.java b/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/UserGroupsWsParameters.java
deleted file mode 100644
index dfb54c5d2aa..00000000000
--- a/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/UserGroupsWsParameters.java
+++ /dev/null
@@ -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");
- }
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/UsersAction.java b/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/UsersAction.java
index 468d0a43d09..604fbc11ce1 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/UsersAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/UsersAction.java
@@ -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) {
diff --git a/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/WsGroupRef.java b/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/WsGroupRef.java
deleted file mode 100644
index a95b34fa071..00000000000
--- a/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/WsGroupRef.java
+++ /dev/null
@@ -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;
- }
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/package-info.java b/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/package-info.java
index d3324e608f4..7ba0a0da3c9 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/package-info.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/package-info.java
@@ -21,4 +21,3 @@
package org.sonar.server.usergroups.ws;
import javax.annotation.ParametersAreNonnullByDefault;
-
diff --git a/server/sonar-server/src/main/resources/org/sonar/server/usergroups/ws/example-create.json b/server/sonar-server/src/main/resources/org/sonar/server/usergroups/ws/example-create.json
index 00f5eb9f6b2..91ea7df4d1a 100644
--- a/server/sonar-server/src/main/resources/org/sonar/server/usergroups/ws/example-create.json
+++ b/server/sonar-server/src/main/resources/org/sonar/server/usergroups/ws/example-create.json
@@ -1,6 +1,7 @@
{
"group": {
"id": "42",
+ "organization": "my-org",
"name": "some-product-bu",
"description": "Business Unit for Some Awesome Product",
"membersCount": 0
diff --git a/server/sonar-server/src/test/java/org/sonar/server/user/ServerUserSessionTest.java b/server/sonar-server/src/test/java/org/sonar/server/user/ServerUserSessionTest.java
index 00b83ec3de6..ebffd03f705 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/user/ServerUserSessionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/user/ServerUserSessionTest.java
@@ -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");
}
-
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/AddUserActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/AddUserActionTest.java
index 58b4f5137a1..dc4f9f555f3 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/AddUserActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/AddUserActionTest.java
@@ -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));
- }
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/CreateActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/CreateActionTest.java
index 0118dd9993d..0953039a70f 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/CreateActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/CreateActionTest.java
@@ -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();
+ }
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/DeleteActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/DeleteActionTest.java
index 05968b480d5..2cdd2e07a25 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/DeleteActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/DeleteActionTest.java
@@ -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);
+ }
+
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/GroupWsRefTest.java b/server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/GroupWsRefTest.java
new file mode 100644
index 00000000000..2afb8fe4b2c
--- /dev/null
+++ b/server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/GroupWsRefTest.java
@@ -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();
+ }
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/RemoveUserActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/RemoveUserActionTest.java
index cc206a856b0..b2a6d1c9dfa 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/RemoveUserActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/RemoveUserActionTest.java
@@ -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));
- }
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/SearchActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/SearchActionTest.java
index b8c65d582db..542a194e5a7 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/SearchActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/SearchActionTest.java
@@ -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));
+ }
+
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/UpdateActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/UpdateActionTest.java
index df57395d868..ba6b7a57339 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/UpdateActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/UpdateActionTest.java
@@ -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);
}
-
-
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/UserGroupsModuleTest.java b/server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/UserGroupsModuleTest.java
index e533bb7f61d..44c4a8dac0b 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/UserGroupsModuleTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/UserGroupsModuleTest.java
@@ -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);
}
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/UserGroupsWsTest.java b/server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/UserGroupsWsTest.java
index 2e8b7a6755e..476c532a510 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/UserGroupsWsTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/UserGroupsWsTest.java
@@ -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);
}
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/UsersActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/UsersActionTest.java
index 4c1b09f0697..af0c949661b 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/UsersActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/UsersActionTest.java
@@ -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()));
- }
}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/user/UserUpdaterTest/associate_default_groups_when_reactivating_user.xml b/server/sonar-server/src/test/resources/org/sonar/server/user/UserUpdaterTest/associate_default_groups_when_reactivating_user.xml
index d2470c724ab..eb584fdc8a0 100644
--- a/server/sonar-server/src/test/resources/org/sonar/server/user/UserUpdaterTest/associate_default_groups_when_reactivating_user.xml
+++ b/server/sonar-server/src/test/resources/org/sonar/server/user/UserUpdaterTest/associate_default_groups_when_reactivating_user.xml
@@ -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"/>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/user/UserUpdaterTest/not_associate_default_group_when_updating_user_if_already_existing.xml b/server/sonar-server/src/test/resources/org/sonar/server/user/UserUpdaterTest/not_associate_default_group_when_updating_user_if_already_existing.xml
index ea65c7abcfd..95ec8776256 100644
--- a/server/sonar-server/src/test/resources/org/sonar/server/user/UserUpdaterTest/not_associate_default_group_when_updating_user_if_already_existing.xml
+++ b/server/sonar-server/src/test/resources/org/sonar/server/user/UserUpdaterTest/not_associate_default_group_when_updating_user_if_already_existing.xml
@@ -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"/>
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1403_add_root_column_on_table_users.rb b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1404_add_root_column_on_table_users.rb
index 154adcc8b60..154adcc8b60 100644
--- a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1403_add_root_column_on_table_users.rb
+++ b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1404_add_root_column_on_table_users.rb
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1404_populate_root_column_on_table_users.rb b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1405_populate_root_column_on_table_users.rb
index d15774555e1..d15774555e1 100644
--- a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1404_populate_root_column_on_table_users.rb
+++ b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1405_populate_root_column_on_table_users.rb
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1405_make_root_column_not_null_on_table_users.rb b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1406_make_root_column_not_null_on_table_users.rb
index 97d9dbea5c7..97d9dbea5c7 100644
--- a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1405_make_root_column_not_null_on_table_users.rb
+++ b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1406_make_root_column_not_null_on_table_users.rb
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1406_populate_organization_uuid_of_groups.rb b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1407_populate_organization_uuid_of_groups.rb
index 3482e679978..3482e679978 100644
--- a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1406_populate_organization_uuid_of_groups.rb
+++ b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1407_populate_organization_uuid_of_groups.rb
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1407_make_organization_uuid_not_null_on_groups.rb b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1408_make_organization_uuid_not_null_on_groups.rb
index d553d1c5614..d553d1c5614 100644
--- a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1407_make_organization_uuid_not_null_on_groups.rb
+++ b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1408_make_organization_uuid_not_null_on_groups.rb
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1408_add_organization_uuid_to_user_roles.rb b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1409_add_organization_uuid_to_user_roles.rb
index 977524cdcb8..977524cdcb8 100644
--- a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1408_add_organization_uuid_to_user_roles.rb
+++ b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1409_add_organization_uuid_to_user_roles.rb
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1409_populate_organization_uuid_of_user_roles.rb b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1410_populate_organization_uuid_of_user_roles.rb
index f26b71b0d0a..f26b71b0d0a 100644
--- a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1409_populate_organization_uuid_of_user_roles.rb
+++ b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1410_populate_organization_uuid_of_user_roles.rb
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1410_make_organization_uuid_not_null_on_user_roles.rb b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1411_make_organization_uuid_not_null_on_user_roles.rb
index ecf2e345f7d..ecf2e345f7d 100644
--- a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1410_make_organization_uuid_not_null_on_user_roles.rb
+++ b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1411_make_organization_uuid_not_null_on_user_roles.rb
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1411_add_organization_uuid_to_permission_templates.rb b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1412_add_organization_uuid_to_permission_templates.rb
index 01d94e19572..01d94e19572 100644
--- a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1411_add_organization_uuid_to_permission_templates.rb
+++ b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1412_add_organization_uuid_to_permission_templates.rb
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1412_populate_organization_uuid_of_permission_templates.rb b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1413_populate_organization_uuid_of_permission_templates.rb
index d855a08cfa0..d855a08cfa0 100644
--- a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1412_populate_organization_uuid_of_permission_templates.rb
+++ b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1413_populate_organization_uuid_of_permission_templates.rb
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1413_make_organization_uuid_not_null_on_permission_templates.rb b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1414_make_organization_uuid_not_null_on_permission_templates.rb
index 8258665b4a1..8258665b4a1 100644
--- a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1413_make_organization_uuid_not_null_on_permission_templates.rb
+++ b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1414_make_organization_uuid_not_null_on_permission_templates.rb