@@ -0,0 +1,38 @@ | |||
/* | |||
* 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.permission; | |||
import javax.annotation.Nullable; | |||
import org.sonar.server.usergroups.ws.GroupIdOrAnyone; | |||
public class GroupPermissionChange extends PermissionChange { | |||
private final GroupIdOrAnyone groupId; | |||
public GroupPermissionChange(Operation operation, String permission, @Nullable ProjectRef projectRef, | |||
GroupIdOrAnyone groupId) { | |||
super(operation, groupId.getOrganizationUuid(), permission, projectRef); | |||
this.groupId = groupId; | |||
} | |||
public GroupIdOrAnyone getGroupIdOrAnyone() { | |||
return groupId; | |||
} | |||
} |
@@ -0,0 +1,100 @@ | |||
/* | |||
* 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.permission; | |||
import java.util.List; | |||
import org.sonar.core.permission.GlobalPermissions; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.permission.GroupPermissionDto; | |||
import org.sonar.server.exceptions.BadRequestException; | |||
import org.sonar.server.user.UserSession; | |||
import static org.sonar.server.permission.ws.PermissionRequestValidator.validateNotAnyoneAndAdminPermission; | |||
public class GroupPermissionChanger { | |||
private final DbClient dbClient; | |||
private final UserSession userSession; | |||
public GroupPermissionChanger(DbClient dbClient, UserSession userSession) { | |||
this.dbClient = dbClient; | |||
this.userSession = userSession; | |||
} | |||
public boolean apply(DbSession dbSession, GroupPermissionChange change) { | |||
PermissionPrivilegeChecker.checkProjectAdminUserByComponentUuid(userSession, change.getProjectUuid()); | |||
if (shouldSkip(dbSession, change)) { | |||
return false; | |||
} | |||
switch (change.getOperation()) { | |||
case ADD: | |||
validateNotAnyoneAndAdminPermission(change.getPermission(), change.getGroupIdOrAnyone()); | |||
GroupPermissionDto addedDto = new GroupPermissionDto() | |||
.setRole(change.getPermission()) | |||
// TODO support organizations | |||
.setGroupId(change.getGroupIdOrAnyone().getId()) | |||
.setResourceId(change.getNullableProjectId()); | |||
dbClient.groupPermissionDao().insert(dbSession, addedDto); | |||
break; | |||
case REMOVE: | |||
checkAdminUsersExistOutsideTheRemovedGroup(dbSession, change); | |||
GroupPermissionDto deletedDto = new GroupPermissionDto() | |||
.setRole(change.getPermission()) | |||
// TODO support organizations | |||
.setGroupId(change.getGroupIdOrAnyone().getId()) | |||
.setResourceId(change.getNullableProjectId()); | |||
dbClient.roleDao().deleteGroupRole(deletedDto, dbSession); | |||
break; | |||
default: | |||
throw new UnsupportedOperationException("Unsupported permission change: " + change.getOperation()); | |||
} | |||
return true; | |||
} | |||
private boolean shouldSkip(DbSession dbSession, GroupPermissionChange change) { | |||
List<String> existingPermissions; | |||
if (change.getGroupIdOrAnyone().isAnyone()) { | |||
existingPermissions = dbClient.groupPermissionDao().selectAnyonePermissions(dbSession, change.getNullableProjectId()); | |||
} else { | |||
existingPermissions = dbClient.groupPermissionDao().selectGroupPermissions(dbSession, change.getGroupIdOrAnyone().getId(), change.getNullableProjectId()); | |||
} | |||
switch (change.getOperation()) { | |||
case ADD: | |||
return existingPermissions.contains(change.getPermission()); | |||
case REMOVE: | |||
return !existingPermissions.contains(change.getPermission()); | |||
default: | |||
throw new UnsupportedOperationException("Unsupported operation: " + change.getOperation()); | |||
} | |||
} | |||
private void checkAdminUsersExistOutsideTheRemovedGroup(DbSession dbSession, GroupPermissionChange change) { | |||
if (GlobalPermissions.SYSTEM_ADMIN.equals(change.getPermission()) && | |||
!change.getProjectRef().isPresent() && | |||
// TODO support organizations | |||
dbClient.roleDao().countUserPermissions(dbSession, change.getPermission(), change.getGroupIdOrAnyone().getId()) <= 0) { | |||
throw new BadRequestException(String.format("Last group with '%s' permission. Permission cannot be removed.", GlobalPermissions.SYSTEM_ADMIN)); | |||
} | |||
} | |||
} |
@@ -19,110 +19,67 @@ | |||
*/ | |||
package org.sonar.server.permission; | |||
import com.google.common.base.Strings; | |||
import java.util.Map; | |||
import java.util.Optional; | |||
import javax.annotation.CheckForNull; | |||
import javax.annotation.Nullable; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.sonar.core.permission.ProjectPermissions; | |||
import org.sonar.core.permission.GlobalPermissions; | |||
import org.sonar.server.exceptions.BadRequestException; | |||
public class PermissionChange { | |||
static final String USER_KEY = "user"; | |||
static final String GROUP_KEY = "group"; | |||
static final String PERMISSION_KEY = "permission"; | |||
static final String COMPONENT_KEY = "component"; | |||
private String userLogin; | |||
private String groupName; | |||
private String componentKey; | |||
private String permission; | |||
import org.sonar.core.permission.ProjectPermissions; | |||
public PermissionChange setUserLogin(@Nullable String login) { | |||
this.userLogin = login; | |||
return this; | |||
} | |||
import static java.util.Objects.requireNonNull; | |||
import static org.sonar.server.ws.WsUtils.checkRequest; | |||
public PermissionChange setGroupName(@Nullable String name) { | |||
this.groupName = name; | |||
return this; | |||
} | |||
public abstract class PermissionChange { | |||
public PermissionChange setComponentKey(@Nullable String componentKey) { | |||
this.componentKey = componentKey; | |||
return this; | |||
public enum Operation { | |||
ADD, REMOVE | |||
} | |||
public PermissionChange setPermission(String permission) { | |||
this.permission = permission; | |||
return this; | |||
private final Operation operation; | |||
private final String organizationUuid; | |||
private final String permission; | |||
private final ProjectRef projectRef; | |||
public PermissionChange(Operation operation, String organizationUuid, String permission, @Nullable ProjectRef projectRef) { | |||
this.operation = requireNonNull(operation); | |||
this.organizationUuid = requireNonNull(organizationUuid); | |||
this.permission = requireNonNull(permission); | |||
this.projectRef = projectRef; | |||
if (projectRef == null) { | |||
checkRequest(GlobalPermissions.ALL.contains(permission), "Invalid global permission '%s'. Valid values are %s", permission, GlobalPermissions.ALL); | |||
} else { | |||
checkRequest(ProjectPermissions.ALL.contains(permission), "Invalid project permission '%s'. Valid values are %s", permission, ProjectPermissions.ALL); | |||
} | |||
} | |||
public static PermissionChange buildFromParams(Map<String, Object> params) { | |||
return new PermissionChange() | |||
.setUserLogin((String) params.get(USER_KEY)) | |||
.setGroupName((String) params.get(GROUP_KEY)) | |||
.setComponentKey((String) params.get(COMPONENT_KEY)) | |||
.setPermission((String) params.get(PERMISSION_KEY)); | |||
public Operation getOperation() { | |||
return operation; | |||
} | |||
void validate() { | |||
validatePermission(); | |||
validateUserGroup(); | |||
public String getOrganizationUuid() { | |||
return organizationUuid; | |||
} | |||
private void validateUserGroup() { | |||
if (StringUtils.isBlank(userLogin) && StringUtils.isBlank(groupName)) { | |||
throw new BadRequestException("Missing user or group parameter"); | |||
} | |||
if (StringUtils.isNotBlank(userLogin) && StringUtils.isNotBlank(groupName)) { | |||
throw new BadRequestException("Only one of user or group parameter should be provided"); | |||
} | |||
} | |||
private void validatePermission() { | |||
if (StringUtils.isBlank(permission)) { | |||
throw new BadRequestException("Missing permission parameter"); | |||
} | |||
if (Strings.isNullOrEmpty(componentKey)) { | |||
if (!GlobalPermissions.ALL.contains(permission)) { | |||
throw new BadRequestException(String.format("Invalid global permission key %s. Valid values are %s", permission, GlobalPermissions.ALL)); | |||
} | |||
} else { | |||
if (!ProjectPermissions.ALL.contains(permission)) { | |||
throw new BadRequestException(String.format("Invalid component permission key %s. Valid values are %s", permission, ProjectPermissions.ALL)); | |||
} | |||
} | |||
public String getPermission() { | |||
return permission; | |||
} | |||
@CheckForNull | |||
public String userLogin() { | |||
return userLogin; | |||
public Optional<ProjectRef> getProjectRef() { | |||
return Optional.ofNullable(projectRef); | |||
} | |||
/** | |||
* Shortcut based on {@link #getProjectRef()} | |||
*/ | |||
@CheckForNull | |||
public String groupName() { | |||
return groupName; | |||
public String getProjectUuid() { | |||
return projectRef == null ? null : projectRef.getUuid(); | |||
} | |||
/** | |||
* Shortcut based on {@link #getProjectRef()} | |||
*/ | |||
@CheckForNull | |||
public String componentKey() { | |||
return componentKey; | |||
} | |||
public String permission() { | |||
return permission; | |||
} | |||
@Override | |||
public String toString() { | |||
return "PermissionChange{" + | |||
"user='" + userLogin + '\'' + | |||
", group='" + groupName + '\'' + | |||
", componentKey='" + componentKey + '\'' + | |||
", permission='" + permission + '\'' + | |||
'}'; | |||
public Long getNullableProjectId() { | |||
return projectRef == null ? null : projectRef.getId(); | |||
} | |||
} |
@@ -19,11 +19,9 @@ | |||
*/ | |||
package org.sonar.server.permission; | |||
import com.google.common.base.Optional; | |||
import javax.annotation.Nullable; | |||
import org.sonar.api.web.UserRole; | |||
import org.sonar.core.permission.GlobalPermissions; | |||
import org.sonar.db.component.ComponentDto; | |||
import org.sonar.server.user.UserSession; | |||
public class PermissionPrivilegeChecker { | |||
@@ -50,12 +48,4 @@ public class PermissionPrivilegeChecker { | |||
userSession.checkPermission(GlobalPermissions.SYSTEM_ADMIN); | |||
} | |||
} | |||
public static void checkProjectAdminUserByComponentDto(UserSession userSession, Optional<ComponentDto> project) { | |||
if (project.isPresent()) { | |||
checkProjectAdminUserByComponentUuid(userSession, project.get().uuid()); | |||
} else { | |||
checkGlobalAdminUser(userSession); | |||
} | |||
} | |||
} |
@@ -55,6 +55,9 @@ public class PermissionService { | |||
this.componentFinder = componentFinder; | |||
} | |||
/** | |||
* Used by Ruby on Rails | |||
*/ | |||
public List<String> globalPermissions() { | |||
return GlobalPermissions.ALL; | |||
} | |||
@@ -95,18 +98,6 @@ public class PermissionService { | |||
return permissionRepository.wouldUserHavePermissionWithDefaultTemplate(dbSession, userId, permission, effectiveKey, qualifier); | |||
} | |||
/** | |||
* Important - this method checks caller permissions | |||
*/ | |||
public void applyPermissionTemplate(ApplyPermissionTemplateQuery query) { | |||
DbSession dbSession = dbClient.openSession(false); | |||
try { | |||
applyPermissionTemplate(dbSession, query); | |||
} finally { | |||
dbClient.closeSession(dbSession); | |||
} | |||
} | |||
public void applyPermissionTemplate(DbSession dbSession, ApplyPermissionTemplateQuery query) { | |||
if (query.getComponentKeys().size() == 1) { | |||
checkProjectAdminUserByComponentKey(userSession, query.getComponentKeys().get(0)); |
@@ -20,189 +20,55 @@ | |||
package org.sonar.server.permission; | |||
import java.util.Collection; | |||
import java.util.List; | |||
import java.util.HashSet; | |||
import java.util.Optional; | |||
import java.util.Set; | |||
import javax.annotation.CheckForNull; | |||
import javax.annotation.Nullable; | |||
import org.sonar.core.permission.GlobalPermissions; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.component.ComponentDto; | |||
import org.sonar.db.permission.PermissionRepository; | |||
import org.sonar.db.user.GroupDto; | |||
import org.sonar.db.user.UserDto; | |||
import org.sonar.server.component.ComponentFinder; | |||
import org.sonar.server.exceptions.BadRequestException; | |||
import org.sonar.server.issue.index.IssueAuthorizationIndexer; | |||
import org.sonar.server.user.UserSession; | |||
import static org.sonar.api.security.DefaultGroups.isAnyone; | |||
import static org.sonar.server.permission.PermissionPrivilegeChecker.checkProjectAdminUserByComponentKey; | |||
import static org.sonar.server.permission.ws.PermissionRequestValidator.validateNotAnyoneAndAdminPermission; | |||
public class PermissionUpdater { | |||
private enum Operation { | |||
ADD, REMOVE | |||
} | |||
private static final String OBJECT_TYPE_USER = "User"; | |||
private static final String OBJECT_TYPE_GROUP = "Group"; | |||
private static final String NOT_FOUND_FORMAT = "%s %s does not exist"; | |||
private final DbClient dbClient; | |||
private final PermissionRepository permissionRepository; | |||
private final IssueAuthorizationIndexer issueAuthorizationIndexer; | |||
private final UserSession userSession; | |||
private final ComponentFinder componentFinder; | |||
private final UserPermissionChanger userPermissionChanger; | |||
private final GroupPermissionChanger groupPermissionChanger; | |||
public PermissionUpdater(DbClient dbClient, PermissionRepository permissionRepository, | |||
IssueAuthorizationIndexer issueAuthorizationIndexer, UserSession userSession, ComponentFinder componentFinder) { | |||
public PermissionUpdater(DbClient dbClient, IssueAuthorizationIndexer issueAuthorizationIndexer, | |||
UserPermissionChanger userPermissionChanger, GroupPermissionChanger groupPermissionChanger) { | |||
this.dbClient = dbClient; | |||
this.permissionRepository = permissionRepository; | |||
this.issueAuthorizationIndexer = issueAuthorizationIndexer; | |||
this.userSession = userSession; | |||
this.componentFinder = componentFinder; | |||
} | |||
public static List<String> globalPermissions() { | |||
return GlobalPermissions.ALL; | |||
} | |||
public void addPermission(PermissionChange change) { | |||
DbSession session = dbClient.openSession(false); | |||
try { | |||
applyChange(Operation.ADD, change, session); | |||
} finally { | |||
dbClient.closeSession(session); | |||
} | |||
} | |||
public void removePermission(PermissionChange change) { | |||
DbSession session = dbClient.openSession(false); | |||
try { | |||
applyChange(Operation.REMOVE, change, session); | |||
} finally { | |||
session.close(); | |||
} | |||
this.userPermissionChanger = userPermissionChanger; | |||
this.groupPermissionChanger = groupPermissionChanger; | |||
} | |||
private void applyChange(Operation operation, PermissionChange change, DbSession session) { | |||
userSession.checkLoggedIn(); | |||
change.validate(); | |||
boolean changed; | |||
if (change.userLogin() != null) { | |||
changed = applyChangeOnUser(session, operation, change); | |||
} else { | |||
changed = applyChangeOnGroup(session, operation, change); | |||
} | |||
if (changed) { | |||
session.commit(); | |||
if (change.componentKey() != null) { | |||
indexProjectPermissions(); | |||
public void apply(DbSession dbSession, Collection<PermissionChange> changes) { | |||
Set<Long> projectIds = new HashSet<>(); | |||
for (PermissionChange change : changes) { | |||
boolean changed = doApply(dbSession, change); | |||
Optional<ProjectRef> projectId = change.getProjectRef(); | |||
if (changed && projectId.isPresent()) { | |||
projectIds.add(projectId.get().getId()); | |||
} | |||
} | |||
} | |||
private boolean applyChangeOnGroup(DbSession session, Operation operation, PermissionChange permissionChange) { | |||
ComponentDto project = getComponent(session, permissionChange.componentKey()); | |||
Long projectId = project != null ? project.getId() : null; | |||
checkProjectAdminUserByComponentKey(userSession, permissionChange.componentKey()); | |||
List<String> existingPermissions = dbClient.roleDao().selectGroupPermissions(session, permissionChange.groupName(), projectId); | |||
if (shouldSkipPermissionChange(operation, existingPermissions, permissionChange)) { | |||
return false; | |||
for (Long projectId : projectIds) { | |||
dbClient.resourceDao().updateAuthorizationDate(projectId, dbSession); | |||
} | |||
dbSession.commit(); | |||
Long targetedGroup = getTargetedGroup(session, permissionChange.groupName()); | |||
String permission = permissionChange.permission(); | |||
if (Operation.ADD == operation) { | |||
validateNotAnyoneAndAdminPermission(permission, permissionChange.groupName()); | |||
permissionRepository.insertGroupPermission(projectId, targetedGroup, permission, session); | |||
} else { | |||
checkAdminUsersExistOutsideTheRemovedGroup(session, permissionChange, targetedGroup); | |||
permissionRepository.deleteGroupPermission(projectId, targetedGroup, permission, session); | |||
if (!projectIds.isEmpty()) { | |||
issueAuthorizationIndexer.index(); | |||
} | |||
return true; | |||
} | |||
private boolean applyChangeOnUser(DbSession session, Operation operation, PermissionChange permissionChange) { | |||
ComponentDto project = getComponent(session, permissionChange.componentKey()); | |||
Long projectId = project != null ? project.getId() : null; | |||
String projectUuid = project != null ? project.uuid() : null; | |||
checkProjectAdminUserByComponentKey(userSession, permissionChange.componentKey()); | |||
Set<String> existingPermissions = dbClient.userPermissionDao().selectPermissionsByLogin(session, permissionChange.userLogin(), projectUuid); | |||
if (shouldSkipPermissionChange(operation, existingPermissions, permissionChange)) { | |||
return false; | |||
private boolean doApply(DbSession dbSession, PermissionChange change) { | |||
if (change instanceof UserPermissionChange) { | |||
return userPermissionChanger.apply(dbSession, (UserPermissionChange) change); | |||
} | |||
UserDto targetedUser = getTargetedUser(session, permissionChange.userLogin()); | |||
if (Operation.ADD == operation) { | |||
permissionRepository.insertUserPermission(projectId, targetedUser.getId(), permissionChange.permission(), session); | |||
} else { | |||
checkOtherAdminUsersExist(session, permissionChange); | |||
permissionRepository.deleteUserPermission(project, targetedUser.getLogin(), permissionChange.permission(), session); | |||
if (change instanceof GroupPermissionChange) { | |||
return groupPermissionChanger.apply(dbSession, (GroupPermissionChange) change); | |||
} | |||
return true; | |||
} | |||
private void checkOtherAdminUsersExist(DbSession session, PermissionChange permissionChange) { | |||
if (GlobalPermissions.SYSTEM_ADMIN.equals(permissionChange.permission()) | |||
&& permissionChange.componentKey() == null | |||
&& dbClient.roleDao().countUserPermissions(session, permissionChange.permission(), null) <= 1) { | |||
throw new BadRequestException(String.format("Last user with '%s' permission. Permission cannot be removed.", GlobalPermissions.SYSTEM_ADMIN)); | |||
} | |||
} | |||
private void checkAdminUsersExistOutsideTheRemovedGroup(DbSession session, PermissionChange permissionChange, @Nullable Long groupIdToExclude) { | |||
if (GlobalPermissions.SYSTEM_ADMIN.equals(permissionChange.permission()) | |||
&& groupIdToExclude != null | |||
&& permissionChange.componentKey() == null | |||
&& dbClient.roleDao().countUserPermissions(session, permissionChange.permission(), groupIdToExclude) <= 0) { | |||
throw new BadRequestException(String.format("Last group with '%s' permission. Permission cannot be removed.", GlobalPermissions.SYSTEM_ADMIN)); | |||
} | |||
} | |||
private UserDto getTargetedUser(DbSession session, String userLogin) { | |||
UserDto user = dbClient.userDao().selectActiveUserByLogin(session, userLogin); | |||
badRequestIfNullResult(user, OBJECT_TYPE_USER, userLogin); | |||
return user; | |||
} | |||
@Nullable | |||
private Long getTargetedGroup(DbSession session, String group) { | |||
if (isAnyone(group)) { | |||
return null; | |||
} else { | |||
GroupDto groupDto = dbClient.groupDao().selectByName(session, group); | |||
badRequestIfNullResult(groupDto, OBJECT_TYPE_GROUP, group); | |||
return groupDto.getId(); | |||
} | |||
} | |||
private static boolean shouldSkipPermissionChange(Operation operation, Collection<String> existingPermissions, PermissionChange permissionChange) { | |||
return (Operation.ADD == operation && existingPermissions.contains(permissionChange.permission())) || | |||
(Operation.REMOVE == operation && !existingPermissions.contains(permissionChange.permission())); | |||
} | |||
@CheckForNull | |||
private ComponentDto getComponent(DbSession session, @Nullable String componentKey) { | |||
if (componentKey == null) { | |||
return null; | |||
} | |||
return componentFinder.getByKey(session, componentKey); | |||
} | |||
private static Object badRequestIfNullResult(@Nullable Object component, String objectType, String objectKey) { | |||
if (component == null) { | |||
throw new BadRequestException(String.format(NOT_FOUND_FORMAT, objectType, objectKey)); | |||
} | |||
return component; | |||
} | |||
throw new UnsupportedOperationException("Unsupported permission change: " + change.getClass()); | |||
private void indexProjectPermissions() { | |||
issueAuthorizationIndexer.index(); | |||
} | |||
} |
@@ -0,0 +1,53 @@ | |||
/* | |||
* 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.permission; | |||
import javax.annotation.concurrent.Immutable; | |||
import org.sonar.db.component.ComponentDto; | |||
import static java.util.Objects.requireNonNull; | |||
/** | |||
* Reference to a project by its db id or uuid. Temporarily | |||
* as long as permissions do not use only uuids. | |||
*/ | |||
@Immutable | |||
public class ProjectRef { | |||
private final long id; | |||
private final String uuid; | |||
public ProjectRef(long projectId, String projectUuid) { | |||
this.id = projectId; | |||
this.uuid = requireNonNull(projectUuid); | |||
} | |||
public ProjectRef(ComponentDto dto) { | |||
this(requireNonNull(dto.getId()), dto.uuid()); | |||
} | |||
public long getId() { | |||
return id; | |||
} | |||
public String getUuid() { | |||
return uuid; | |||
} | |||
} |
@@ -0,0 +1,49 @@ | |||
/* | |||
* 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.permission; | |||
import javax.annotation.concurrent.Immutable; | |||
import static java.util.Objects.requireNonNull; | |||
/** | |||
* Reference a user by his technical (db) id or functional login. | |||
* This is temporary class as long as services and DAOs do not | |||
* use only technical id. | |||
*/ | |||
@Immutable | |||
public class UserId { | |||
private final long id; | |||
private final String login; | |||
public UserId(long userId, String login) { | |||
this.id = userId; | |||
this.login = requireNonNull(login); | |||
} | |||
public long getId() { | |||
return id; | |||
} | |||
public String getLogin() { | |||
return login; | |||
} | |||
} |
@@ -0,0 +1,39 @@ | |||
/* | |||
* 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.permission; | |||
import javax.annotation.Nullable; | |||
import static java.util.Objects.requireNonNull; | |||
public class UserPermissionChange extends PermissionChange { | |||
private final UserId userId; | |||
public UserPermissionChange(Operation operation, String organizationUuid, String permission, @Nullable ProjectRef projectRef, | |||
UserId userId) { | |||
super(operation, organizationUuid, permission, projectRef); | |||
this.userId = requireNonNull(userId); | |||
} | |||
public UserId getUserId() { | |||
return userId; | |||
} | |||
} |
@@ -0,0 +1,78 @@ | |||
/* | |||
* 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.permission; | |||
import java.util.Set; | |||
import org.sonar.core.permission.GlobalPermissions; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.permission.UserPermissionDto; | |||
import org.sonar.server.exceptions.BadRequestException; | |||
import org.sonar.server.permission.PermissionChange.Operation; | |||
import org.sonar.server.user.UserSession; | |||
import static org.sonar.server.permission.PermissionPrivilegeChecker.checkProjectAdminUserByComponentUuid; | |||
public class UserPermissionChanger { | |||
private final DbClient dbClient; | |||
private final UserSession userSession; | |||
public UserPermissionChanger(DbClient dbClient, UserSession userSession) { | |||
this.dbClient = dbClient; | |||
this.userSession = userSession; | |||
} | |||
public boolean apply(DbSession dbSession, UserPermissionChange change) { | |||
checkProjectAdminUserByComponentUuid(userSession, change.getProjectUuid()); | |||
if (shouldSkipChange(dbSession, change)) { | |||
return false; | |||
} | |||
switch (change.getOperation()) { | |||
case ADD: | |||
UserPermissionDto dto = new UserPermissionDto(change.getOrganizationUuid(), change.getPermission(), change.getUserId().getId(), change.getNullableProjectId()); | |||
dbClient.userPermissionDao().insert(dbSession, dto); | |||
break; | |||
case REMOVE: | |||
checkOtherAdminUsersExist(dbSession, change); | |||
dbClient.userPermissionDao().delete(dbSession, change.getUserId().getLogin(), change.getProjectUuid(), change.getPermission()); | |||
break; | |||
default: | |||
throw new UnsupportedOperationException("Unsupported permission change: " + change.getOperation()); | |||
} | |||
return true; | |||
} | |||
private boolean shouldSkipChange(DbSession dbSession, UserPermissionChange change) { | |||
Set<String> existingPermissions = dbClient.userPermissionDao().selectPermissionsByLogin(dbSession, change.getUserId().getLogin(), change.getProjectUuid()); | |||
return (Operation.ADD == change.getOperation() && existingPermissions.contains(change.getPermission())) || | |||
(Operation.REMOVE == change.getOperation() && !existingPermissions.contains(change.getPermission())); | |||
} | |||
private void checkOtherAdminUsersExist(DbSession session, PermissionChange change) { | |||
if (GlobalPermissions.SYSTEM_ADMIN.equals(change.getPermission()) && | |||
!change.getProjectRef().isPresent() && | |||
dbClient.roleDao().countUserPermissions(session, change.getPermission(), null) <= 1) { | |||
throw new BadRequestException(String.format("Last user with '%s' permission. Permission cannot be removed.", GlobalPermissions.SYSTEM_ADMIN)); | |||
} | |||
} | |||
} |
@@ -19,39 +19,37 @@ | |||
*/ | |||
package org.sonar.server.permission.ws; | |||
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; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.server.permission.GroupPermissionChange; | |||
import org.sonar.server.permission.PermissionChange; | |||
import org.sonar.server.permission.PermissionUpdater; | |||
import org.sonarqube.ws.client.permission.AddGroupWsRequest; | |||
import org.sonar.server.permission.ProjectRef; | |||
import org.sonar.server.usergroups.ws.GroupIdOrAnyone; | |||
import static java.util.Arrays.asList; | |||
import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createGroupIdParameter; | |||
import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createGroupNameParameter; | |||
import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createPermissionParameter; | |||
import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createProjectParameters; | |||
import static org.sonar.server.permission.ws.WsProjectRef.newOptionalWsProjectRef; | |||
import static org.sonar.server.usergroups.ws.WsGroupRef.newWsGroupRef; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_GROUP_ID; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_GROUP_NAME; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PERMISSION; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PROJECT_ID; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PROJECT_KEY; | |||
public class AddGroupAction implements PermissionsWsAction { | |||
public static final String ACTION = "add_group"; | |||
private final DbClient dbClient; | |||
private final PermissionChangeBuilder permissionChangeBuilder; | |||
private final PermissionUpdater permissionUpdater; | |||
private final PermissionWsSupport support; | |||
public AddGroupAction(DbClient dbClient, PermissionChangeBuilder permissionChangeBuilder, PermissionUpdater permissionUpdater) { | |||
this.permissionChangeBuilder = permissionChangeBuilder; | |||
this.permissionUpdater = permissionUpdater; | |||
public AddGroupAction(DbClient dbClient, PermissionUpdater permissionUpdater, PermissionWsSupport support) { | |||
this.dbClient = dbClient; | |||
this.permissionUpdater = permissionUpdater; | |||
this.support = support; | |||
} | |||
@Override | |||
@@ -73,33 +71,18 @@ public class AddGroupAction implements PermissionsWsAction { | |||
@Override | |||
public void handle(Request request, Response response) throws Exception { | |||
AddGroupWsRequest addGroupWsRequest = toAddGroupWsRequest(request); | |||
doHandle(addGroupWsRequest); | |||
try (DbSession dbSession = dbClient.openSession(false)) { | |||
GroupIdOrAnyone group = support.findGroup(dbSession, request); | |||
Optional<ProjectRef> projectId = support.findProject(dbSession, request); | |||
response.noContent(); | |||
} | |||
private void doHandle(AddGroupWsRequest request) { | |||
DbSession dbSession = dbClient.openSession(false); | |||
try { | |||
Long groupId = request.getGroupId() == null ? null : Long.valueOf(request.getGroupId()); | |||
PermissionChange permissionChange = permissionChangeBuilder.buildGroupPermissionChange( | |||
dbSession, | |||
request.getPermission(), | |||
newOptionalWsProjectRef(request.getProjectId(), request.getProjectKey()), | |||
newWsGroupRef(groupId, request.getGroupName())); | |||
permissionUpdater.addPermission(permissionChange); | |||
} finally { | |||
dbClient.closeSession(dbSession); | |||
PermissionChange change = new GroupPermissionChange( | |||
PermissionChange.Operation.ADD, | |||
request.mandatoryParam(PARAM_PERMISSION), | |||
projectId.orElse(null), | |||
group); | |||
permissionUpdater.apply(dbSession, asList(change)); | |||
} | |||
response.noContent(); | |||
} | |||
private static AddGroupWsRequest toAddGroupWsRequest(Request request) { | |||
return new AddGroupWsRequest() | |||
.setPermission(request.mandatoryParam(PARAM_PERMISSION)) | |||
.setGroupId(request.param(PARAM_GROUP_ID)) | |||
.setGroupName(request.param(PARAM_GROUP_NAME)) | |||
.setProjectId(request.param(PARAM_PROJECT_ID)) | |||
.setProjectKey(request.param(PARAM_PROJECT_KEY)); | |||
} | |||
} |
@@ -19,24 +19,26 @@ | |||
*/ | |||
package org.sonar.server.permission.ws; | |||
import com.google.common.base.Optional; | |||
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; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.organization.OrganizationDto; | |||
import org.sonar.server.permission.PermissionChange; | |||
import org.sonar.server.permission.PermissionUpdater; | |||
import org.sonarqube.ws.client.permission.AddUserWsRequest; | |||
import org.sonar.server.permission.ProjectRef; | |||
import org.sonar.server.permission.UserId; | |||
import org.sonar.server.permission.UserPermissionChange; | |||
import static org.sonar.server.permission.ws.PermissionRequestValidator.validatePermission; | |||
import static java.util.Arrays.asList; | |||
import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createOrganizationParameter; | |||
import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createPermissionParameter; | |||
import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createProjectParameters; | |||
import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createUserLoginParameter; | |||
import static org.sonar.server.permission.ws.WsProjectRef.newOptionalWsProjectRef; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_ORGANIZATION_KEY; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PERMISSION; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PROJECT_ID; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PROJECT_KEY; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_USER_LOGIN; | |||
public class AddUserAction implements PermissionsWsAction { | |||
@@ -45,12 +47,12 @@ public class AddUserAction implements PermissionsWsAction { | |||
private final DbClient dbClient; | |||
private final PermissionUpdater permissionUpdater; | |||
private final PermissionChangeBuilder permissionChangeBuilder; | |||
private final PermissionWsSupport support; | |||
public AddUserAction(DbClient dbClient, PermissionUpdater permissionUpdater, PermissionChangeBuilder permissionWsCommons) { | |||
public AddUserAction(DbClient dbClient, PermissionUpdater permissionUpdater, PermissionWsSupport support) { | |||
this.dbClient = dbClient; | |||
this.permissionUpdater = permissionUpdater; | |||
this.permissionChangeBuilder = permissionWsCommons; | |||
this.support = support; | |||
} | |||
@Override | |||
@@ -66,36 +68,23 @@ public class AddUserAction implements PermissionsWsAction { | |||
createPermissionParameter(action); | |||
createUserLoginParameter(action); | |||
createProjectParameters(action); | |||
createOrganizationParameter(action); | |||
} | |||
@Override | |||
public void handle(Request request, Response response) throws Exception { | |||
doHandle(toAddUserWsRequest(request)); | |||
response.noContent(); | |||
} | |||
private void doHandle(AddUserWsRequest request) { | |||
Optional<WsProjectRef> projectRef = newOptionalWsProjectRef(request.getProjectId(), request.getProjectKey()); | |||
validatePermission(request.getPermission(), projectRef); | |||
DbSession dbSession = dbClient.openSession(false); | |||
try { | |||
PermissionChange permissionChange = permissionChangeBuilder.buildUserPermissionChange( | |||
dbSession, | |||
request.getPermission(), | |||
projectRef, | |||
request.getLogin()); | |||
permissionUpdater.addPermission(permissionChange); | |||
} finally { | |||
dbClient.closeSession(dbSession); | |||
try (DbSession dbSession = dbClient.openSession(false)) { | |||
UserId user = support.findUser(dbSession, request.mandatoryParam(PARAM_USER_LOGIN)); | |||
Optional<ProjectRef> projectId = support.findProject(dbSession, request); | |||
OrganizationDto org = support.findOrganization(dbSession, request.param(PARAM_ORGANIZATION_KEY)); | |||
PermissionChange change = new UserPermissionChange( | |||
PermissionChange.Operation.ADD, | |||
org.getUuid(), | |||
request.mandatoryParam(PARAM_PERMISSION), | |||
projectId.orElse(null), | |||
user); | |||
permissionUpdater.apply(dbSession, asList(change)); | |||
} | |||
} | |||
private static AddUserWsRequest toAddUserWsRequest(Request request) { | |||
return new AddUserWsRequest() | |||
.setPermission(request.mandatoryParam(PARAM_PERMISSION)) | |||
.setLogin(request.mandatoryParam(PARAM_USER_LOGIN)) | |||
.setProjectId(request.param(PARAM_PROJECT_ID)) | |||
.setProjectKey(request.param(PARAM_PROJECT_KEY)); | |||
response.noContent(); | |||
} | |||
} |
@@ -19,12 +19,12 @@ | |||
*/ | |||
package org.sonar.server.permission.ws; | |||
import com.google.common.base.Optional; | |||
import com.google.common.collect.Multimap; | |||
import com.google.common.collect.Ordering; | |||
import com.google.common.collect.TreeMultimap; | |||
import com.google.common.io.Resources; | |||
import java.util.List; | |||
import java.util.Optional; | |||
import java.util.stream.Collectors; | |||
import org.sonar.api.security.DefaultGroups; | |||
import org.sonar.api.server.ws.Request; | |||
@@ -34,38 +34,33 @@ import org.sonar.api.server.ws.WebService.Param; | |||
import org.sonar.api.utils.Paging; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.component.ComponentDto; | |||
import org.sonar.db.permission.GroupPermissionDto; | |||
import org.sonar.db.permission.PermissionQuery; | |||
import org.sonar.db.user.GroupDto; | |||
import org.sonar.db.permission.GroupPermissionDto; | |||
import org.sonar.server.permission.ProjectRef; | |||
import org.sonar.server.user.UserSession; | |||
import org.sonarqube.ws.WsPermissions.Group; | |||
import org.sonarqube.ws.WsPermissions.WsGroupsResponse; | |||
import org.sonarqube.ws.client.permission.GroupsWsRequest; | |||
import static java.util.Collections.emptyList; | |||
import static org.sonar.db.permission.PermissionQuery.DEFAULT_PAGE_SIZE; | |||
import static org.sonar.db.permission.PermissionQuery.RESULTS_MAX_SIZE; | |||
import static org.sonar.db.permission.PermissionQuery.SEARCH_QUERY_MIN_LENGTH; | |||
import static org.sonar.server.permission.PermissionPrivilegeChecker.checkProjectAdminUserByComponentDto; | |||
import static org.sonar.server.permission.ws.PermissionRequestValidator.validatePermission; | |||
import static org.sonar.server.permission.PermissionPrivilegeChecker.checkProjectAdminUserByComponentUuid; | |||
import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createPermissionParameter; | |||
import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createProjectParameters; | |||
import static org.sonar.server.permission.ws.WsProjectRef.newOptionalWsProjectRef; | |||
import static org.sonar.server.ws.WsUtils.writeProtobuf; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PERMISSION; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PROJECT_ID; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PROJECT_KEY; | |||
public class GroupsAction implements PermissionsWsAction { | |||
private final DbClient dbClient; | |||
private final UserSession userSession; | |||
private final PermissionDependenciesFinder dependenciesFinder; | |||
private final PermissionWsSupport support; | |||
public GroupsAction(DbClient dbClient, UserSession userSession, PermissionDependenciesFinder dependenciesFinder) { | |||
public GroupsAction(DbClient dbClient, UserSession userSession, PermissionWsSupport support) { | |||
this.dbClient = dbClient; | |||
this.userSession = userSession; | |||
this.dependenciesFinder = dependenciesFinder; | |||
this.support = support; | |||
} | |||
@Override | |||
@@ -83,58 +78,39 @@ public class GroupsAction implements PermissionsWsAction { | |||
.setResponseExample(Resources.getResource(getClass(), "groups-example.json")) | |||
.setHandler(this); | |||
createPermissionParameter(action) | |||
.setRequired(false); | |||
// TODO add orgKey | |||
createPermissionParameter(action).setRequired(false); | |||
createProjectParameters(action); | |||
} | |||
@Override | |||
public void handle(Request wsRequest, Response wsResponse) throws Exception { | |||
GroupsWsRequest groupsRequest = toGroupsWsRequest(wsRequest); | |||
WsGroupsResponse groupsResponse = doHandle(groupsRequest); | |||
writeProtobuf(groupsResponse, wsRequest, wsResponse); | |||
} | |||
private WsGroupsResponse doHandle(GroupsWsRequest request) { | |||
DbSession dbSession = dbClient.openSession(false); | |||
try { | |||
Optional<ComponentDto> project = dependenciesFinder.searchProject(dbSession, newOptionalWsProjectRef(request.getProjectId(), request.getProjectKey())); | |||
checkProjectAdminUserByComponentDto(userSession, project); | |||
PermissionQuery dbQuery = buildPermissionQuery(request, project); | |||
List<GroupDto> groups = findGroups(dbSession, dbQuery); | |||
int total = dbClient.groupPermissionDao().countGroupsByPermissionQuery(dbSession, dbQuery); | |||
List<GroupPermissionDto> groupsWithPermission = findGroupPermissions(dbSession, groups, project); | |||
return buildResponse(groups, groupsWithPermission, Paging.forPageIndex(request.getPage()).withPageSize(request.getPageSize()).andTotal(total)); | |||
} finally { | |||
dbClient.closeSession(dbSession); | |||
public void handle(Request request, Response response) throws Exception { | |||
try (DbSession dbSession = dbClient.openSession(false)) { | |||
Optional<ProjectRef> projectId = support.findProject(dbSession, request); | |||
checkProjectAdminUserByComponentUuid(userSession, projectId.isPresent() ? projectId.get().getUuid() : null); | |||
PermissionQuery query = buildPermissionQuery(request, projectId); | |||
// TODO validatePermission(groupsRequest.getPermission(), wsProjectRef); | |||
List<GroupDto> groups = findGroups(dbSession, query); | |||
int total = dbClient.groupPermissionDao().countGroupsByPermissionQuery(dbSession, query); | |||
List<GroupPermissionDto> groupsWithPermission = findGroupPermissions(dbSession, groups, projectId); | |||
Paging paging = Paging.forPageIndex(request.mandatoryParamAsInt(Param.PAGE)).withPageSize(query.getPageSize()).andTotal(total); | |||
WsGroupsResponse groupsResponse = buildResponse(groups, groupsWithPermission, paging); | |||
writeProtobuf(groupsResponse, request, response); | |||
} | |||
} | |||
private static GroupsWsRequest toGroupsWsRequest(Request request) { | |||
GroupsWsRequest groupsRequest = new GroupsWsRequest() | |||
private static PermissionQuery buildPermissionQuery(Request request, Optional<ProjectRef> project) { | |||
String textQuery = request.param(Param.TEXT_QUERY); | |||
PermissionQuery.Builder permissionQuery = PermissionQuery.builder() | |||
.setPermission(request.param(PARAM_PERMISSION)) | |||
.setProjectId(request.param(PARAM_PROJECT_ID)) | |||
.setProjectKey(request.param(PARAM_PROJECT_KEY)) | |||
.setPage(request.mandatoryParamAsInt(Param.PAGE)) | |||
.setPageIndex(request.mandatoryParamAsInt(Param.PAGE)) | |||
.setPageSize(request.mandatoryParamAsInt(Param.PAGE_SIZE)) | |||
.setQuery(request.param(Param.TEXT_QUERY)); | |||
Optional<WsProjectRef> wsProjectRef = newOptionalWsProjectRef(groupsRequest.getProjectId(), groupsRequest.getProjectKey()); | |||
validatePermission(groupsRequest.getPermission(), wsProjectRef); | |||
return groupsRequest; | |||
} | |||
private static PermissionQuery buildPermissionQuery(GroupsWsRequest request, Optional<ComponentDto> project) { | |||
PermissionQuery.Builder permissionQuery = PermissionQuery.builder() | |||
.setPermission(request.getPermission()) | |||
.setPageIndex(request.getPage()) | |||
.setPageSize(request.getPageSize()) | |||
.setSearchQuery(request.getQuery()); | |||
.setSearchQuery(textQuery); | |||
if (project.isPresent()) { | |||
permissionQuery.setComponentUuid(project.get().uuid()); | |||
permissionQuery.setComponentUuid(project.get().getUuid()); | |||
} | |||
if (request.getQuery() == null) { | |||
if (textQuery == null) { | |||
permissionQuery.withAtLeastOnePermission(); | |||
} | |||
return permissionQuery.build(); | |||
@@ -166,6 +142,7 @@ public class GroupsAction implements PermissionsWsAction { | |||
} | |||
private List<GroupDto> findGroups(DbSession dbSession, PermissionQuery dbQuery) { | |||
// TODO support organizations | |||
List<String> orderedNames = dbClient.groupPermissionDao().selectGroupNamesByPermissionQuery(dbSession, dbQuery); | |||
List<GroupDto> groups = dbClient.groupDao().selectByNames(dbSession, orderedNames); | |||
if (orderedNames.contains(DefaultGroups.ANYONE)) { | |||
@@ -174,10 +151,11 @@ public class GroupsAction implements PermissionsWsAction { | |||
return Ordering.explicit(orderedNames).onResultOf(GroupDto::getName).immutableSortedCopy(groups); | |||
} | |||
private List<GroupPermissionDto> findGroupPermissions(DbSession dbSession, List<GroupDto> groups, Optional<ComponentDto> project) { | |||
private List<GroupPermissionDto> findGroupPermissions(DbSession dbSession, List<GroupDto> groups, Optional<ProjectRef> project) { | |||
if (groups.isEmpty()) { | |||
return emptyList(); | |||
} | |||
// TODO use groupId | |||
List<String> names = groups.stream().map(GroupDto::getName).collect(Collectors.toList()); | |||
return dbClient.groupPermissionDao().selectGroupPermissionsByGroupNamesAndProject(dbSession, names, project.isPresent() ? project.get().getId() : null); | |||
} |
@@ -1,65 +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.permission.ws; | |||
import com.google.common.base.Optional; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.component.ComponentDto; | |||
import org.sonar.server.permission.PermissionChange; | |||
import org.sonar.server.usergroups.ws.WsGroupRef; | |||
import static org.sonar.server.permission.ws.PermissionRequestValidator.validatePermission; | |||
public class PermissionChangeBuilder { | |||
private final PermissionDependenciesFinder dependenciesFinder; | |||
public PermissionChangeBuilder(PermissionDependenciesFinder dependenciesFinder) { | |||
this.dependenciesFinder = dependenciesFinder; | |||
} | |||
public PermissionChange buildUserPermissionChange(DbSession dbSession, String permission, Optional<WsProjectRef> projectRef, String login) { | |||
PermissionChange permissionChange = new PermissionChange() | |||
.setPermission(permission) | |||
.setUserLogin(login); | |||
addProjectToPermissionChange(dbSession, permissionChange, projectRef); | |||
return permissionChange; | |||
} | |||
public PermissionChange buildGroupPermissionChange(DbSession dbSession, String permission, Optional<WsProjectRef> projectRef, WsGroupRef groupRef) { | |||
validatePermission(permission, projectRef); | |||
String groupName = dependenciesFinder.getGroupName(dbSession, groupRef); | |||
PermissionChange permissionChange = new PermissionChange() | |||
.setPermission(permission) | |||
.setGroupName(groupName); | |||
addProjectToPermissionChange(dbSession, permissionChange, projectRef); | |||
return permissionChange; | |||
} | |||
private void addProjectToPermissionChange(DbSession dbSession, PermissionChange permissionChange, Optional<WsProjectRef> projectRef) { | |||
Optional<ComponentDto> project = dependenciesFinder.searchProject(dbSession, projectRef); | |||
if (project.isPresent()) { | |||
permissionChange.setComponentKey(project.get().key()); | |||
} | |||
} | |||
} |
@@ -1,103 +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.permission.ws; | |||
import com.google.common.base.Optional; | |||
import javax.annotation.CheckForNull; | |||
import org.sonar.api.resources.ResourceTypes; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.component.ComponentDto; | |||
import org.sonar.db.permission.template.PermissionTemplateDto; | |||
import org.sonar.db.user.GroupDto; | |||
import org.sonar.db.user.UserDto; | |||
import org.sonar.server.component.ComponentFinder; | |||
import org.sonar.server.usergroups.ws.UserGroupFinder; | |||
import org.sonar.server.usergroups.ws.WsGroupRef; | |||
import static org.sonar.api.security.DefaultGroups.ANYONE; | |||
import static org.sonar.api.security.DefaultGroups.isAnyone; | |||
import static org.sonar.server.ws.WsUtils.checkFound; | |||
public class PermissionDependenciesFinder { | |||
private final DbClient dbClient; | |||
private final ComponentFinder componentFinder; | |||
private final UserGroupFinder userGroupFinder; | |||
private final ResourceTypes resourceTypes; | |||
public PermissionDependenciesFinder(DbClient dbClient, ComponentFinder componentFinder, UserGroupFinder userGroupFinder, ResourceTypes resourceTypes) { | |||
this.dbClient = dbClient; | |||
this.componentFinder = componentFinder; | |||
this.userGroupFinder = userGroupFinder; | |||
this.resourceTypes = resourceTypes; | |||
} | |||
/** | |||
* @throws org.sonar.server.exceptions.NotFoundException if a project identifier is provided but it's not found | |||
*/ | |||
Optional<ComponentDto> searchProject(DbSession dbSession, Optional<WsProjectRef> optionalWsProjectRef) { | |||
if (!optionalWsProjectRef.isPresent()) { | |||
return Optional.absent(); | |||
} | |||
WsProjectRef wsProjectRef = optionalWsProjectRef.get(); | |||
return Optional.of(componentFinder.getRootComponentOrModuleByUuidOrKey(dbSession, wsProjectRef.uuid(), wsProjectRef.key(), resourceTypes)); | |||
} | |||
public ComponentDto getRootComponentOrModule(DbSession dbSession, WsProjectRef projectRef) { | |||
return componentFinder.getRootComponentOrModuleByUuidOrKey(dbSession, projectRef.uuid(), projectRef.key(), resourceTypes); | |||
} | |||
String getGroupName(DbSession dbSession, WsGroupRef groupRef) { | |||
GroupDto group = getGroup(dbSession, groupRef); | |||
return group == null ? ANYONE : group.getName(); | |||
} | |||
/** | |||
* | |||
* @return null if it's the anyone group | |||
*/ | |||
@CheckForNull | |||
public GroupDto getGroup(DbSession dbSession, WsGroupRef group) { | |||
if (isAnyone(group.name())) { | |||
return null; | |||
} | |||
return userGroupFinder.getGroup(dbSession, group); | |||
} | |||
public UserDto getUser(DbSession dbSession, String userLogin) { | |||
return checkFound(dbClient.userDao().selectActiveUserByLogin(dbSession, userLogin), | |||
"User with login '%s' is not found'", userLogin); | |||
} | |||
public PermissionTemplateDto getTemplate(DbSession dbSession, WsTemplateRef template) { | |||
if (template.uuid() != null) { | |||
return checkFound( | |||
dbClient.permissionTemplateDao().selectByUuid(dbSession, template.uuid()), | |||
"Permission template with id '%s' is not found", template.uuid()); | |||
} else { | |||
return checkFound( | |||
dbClient.permissionTemplateDao().selectByName(dbSession, template.name()), | |||
"Permission template with name '%s' is not found (case insensitive)", template.name()); | |||
} | |||
} | |||
} |
@@ -19,7 +19,6 @@ | |||
*/ | |||
package org.sonar.server.permission.ws; | |||
import com.google.common.base.Optional; | |||
import com.google.common.collect.FluentIterable; | |||
import java.util.Set; | |||
import java.util.regex.Pattern; | |||
@@ -29,11 +28,11 @@ import org.sonar.api.resources.ResourceTypes; | |||
import org.sonar.core.permission.GlobalPermissions; | |||
import org.sonar.core.permission.ProjectPermissions; | |||
import org.sonar.server.exceptions.BadRequestException; | |||
import org.sonar.server.usergroups.ws.GroupIdOrAnyone; | |||
import static com.google.common.base.Strings.isNullOrEmpty; | |||
import static java.lang.String.format; | |||
import static org.apache.commons.lang.StringUtils.isBlank; | |||
import static org.sonar.api.security.DefaultGroups.isAnyone; | |||
import static org.sonar.server.component.ResourceTypeFunctions.RESOURCE_TYPE_TO_QUALIFIER; | |||
import static org.sonar.server.ws.WsUtils.checkRequest; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PERMISSION; | |||
@@ -48,17 +47,6 @@ public class PermissionRequestValidator { | |||
// static methods only | |||
} | |||
public static void validatePermission(@Nullable String permission, Optional<WsProjectRef> projectRef) { | |||
if (permission == null) { | |||
return; | |||
} | |||
if (projectRef.isPresent()) { | |||
validateProjectPermission(permission); | |||
} else { | |||
validateGlobalPermission(permission); | |||
} | |||
} | |||
public static String validateProjectPermission(String permission) { | |||
checkRequest(ProjectPermissions.ALL.contains(permission), | |||
format("The '%s' parameter for project permissions must be one of %s. '%s' was passed.", PARAM_PERMISSION, ProjectPermissions.ALL_ON_ONE_LINE, permission)); | |||
@@ -70,9 +58,9 @@ public class PermissionRequestValidator { | |||
format("The '%s' parameter for global permissions must be one of %s. '%s' was passed.", PARAM_PERMISSION, GlobalPermissions.ALL_ON_ONE_LINE, permission)); | |||
} | |||
public static void validateNotAnyoneAndAdminPermission(String permission, @Nullable String groupName) { | |||
checkRequest(!GlobalPermissions.SYSTEM_ADMIN.equals(permission) || !isAnyone(groupName), | |||
format("It is not possible to add the '%s' permission to the '%s' group.", permission, groupName)); | |||
public static void validateNotAnyoneAndAdminPermission(String permission, GroupIdOrAnyone group) { | |||
checkRequest(!GlobalPermissions.SYSTEM_ADMIN.equals(permission) || !group.isAnyone(), | |||
format("It is not possible to add the '%s' permission to group 'Anyone'.", permission)); | |||
} | |||
public static void validateTemplateNameFormat(String name) { |
@@ -0,0 +1,111 @@ | |||
/* | |||
* 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.permission.ws; | |||
import java.util.Optional; | |||
import javax.annotation.Nullable; | |||
import org.sonar.api.resources.ResourceTypes; | |||
import org.sonar.api.server.ws.Request; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.component.ComponentDto; | |||
import org.sonar.db.organization.OrganizationDto; | |||
import org.sonar.db.permission.template.PermissionTemplateDto; | |||
import org.sonar.db.user.UserDto; | |||
import org.sonar.server.component.ComponentFinder; | |||
import org.sonar.server.permission.ProjectRef; | |||
import org.sonar.server.permission.UserId; | |||
import org.sonar.server.permission.ws.template.WsTemplateRef; | |||
import org.sonar.server.usergroups.ws.GroupIdOrAnyone; | |||
import org.sonar.server.usergroups.ws.GroupWsRef; | |||
import org.sonar.server.usergroups.ws.GroupWsSupport; | |||
import org.sonarqube.ws.client.permission.PermissionsWsParameters; | |||
import static org.sonar.server.ws.WsUtils.checkFound; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_GROUP_ID; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_GROUP_NAME; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_ORGANIZATION_KEY; | |||
public class PermissionWsSupport { | |||
private final DbClient dbClient; | |||
private final ComponentFinder componentFinder; | |||
private final GroupWsSupport groupWsSupport; | |||
private final ResourceTypes resourceTypes; | |||
public PermissionWsSupport(DbClient dbClient, ComponentFinder componentFinder, GroupWsSupport groupWsSupport, ResourceTypes resourceTypes) { | |||
this.dbClient = dbClient; | |||
this.componentFinder = componentFinder; | |||
this.groupWsSupport = groupWsSupport; | |||
this.resourceTypes = resourceTypes; | |||
} | |||
public OrganizationDto findOrganization(DbSession dbSession, @Nullable String organizationKey) { | |||
return groupWsSupport.findOrganizationByKey(dbSession, organizationKey); | |||
} | |||
/** | |||
* @throws org.sonar.server.exceptions.NotFoundException if a project does not exist | |||
*/ | |||
public ProjectRef findProject(DbSession dbSession, WsProjectRef ref) { | |||
ComponentDto project = componentFinder.getRootComponentOrModuleByUuidOrKey(dbSession, ref.uuid(), ref.key(), resourceTypes); | |||
return new ProjectRef(project.getId(), project.uuid()); | |||
} | |||
public Optional<ProjectRef> findProject(DbSession dbSession, Request request) { | |||
String uuid = request.param(PermissionsWsParameters.PARAM_PROJECT_ID); | |||
String key = request.param(PermissionsWsParameters.PARAM_PROJECT_KEY); | |||
if (uuid != null || key != null) { | |||
WsProjectRef ref = WsProjectRef.newWsProjectRef(uuid, key); | |||
return Optional.of(findProject(dbSession, ref)); | |||
} | |||
return Optional.empty(); | |||
} | |||
public ComponentDto getRootComponentOrModule(DbSession dbSession, WsProjectRef projectRef) { | |||
return componentFinder.getRootComponentOrModuleByUuidOrKey(dbSession, projectRef.uuid(), projectRef.key(), resourceTypes); | |||
} | |||
public GroupIdOrAnyone findGroup(DbSession dbSession, Request request) { | |||
Long groupId = request.paramAsLong(PARAM_GROUP_ID); | |||
String orgKey = request.param(PARAM_ORGANIZATION_KEY); | |||
String groupName = request.param(PARAM_GROUP_NAME); | |||
GroupWsRef groupRef = GroupWsRef.create(groupId, orgKey, groupName); | |||
return groupWsSupport.findGroupOrAnyone(dbSession, groupRef); | |||
} | |||
public UserId findUser(DbSession dbSession, String login) { | |||
UserDto dto = dbClient.userDao().selectActiveUserByLogin(dbSession, login); | |||
checkFound(dto, "User with login '%s' is not found'", login); | |||
return new UserId(dto.getId(), dto.getLogin()); | |||
} | |||
public PermissionTemplateDto findTemplate(DbSession dbSession, WsTemplateRef ref) { | |||
if (ref.uuid() != null) { | |||
return checkFound( | |||
dbClient.permissionTemplateDao().selectByUuid(dbSession, ref.uuid()), | |||
"Permission template with id '%s' is not found", ref.uuid()); | |||
} else { | |||
return checkFound( | |||
dbClient.permissionTemplateDao().selectByName(dbSession, ref.name()), | |||
"Permission template with name '%s' is not found (case insensitive)", ref.name()); | |||
} | |||
} | |||
} |
@@ -20,6 +20,11 @@ | |||
package org.sonar.server.permission.ws; | |||
import org.sonar.core.platform.Module; | |||
import org.sonar.db.permission.PermissionRepository; | |||
import org.sonar.server.permission.GroupPermissionChanger; | |||
import org.sonar.server.permission.PermissionService; | |||
import org.sonar.server.permission.PermissionUpdater; | |||
import org.sonar.server.permission.UserPermissionChanger; | |||
import org.sonar.server.permission.ws.template.AddGroupToTemplateAction; | |||
import org.sonar.server.permission.ws.template.AddProjectCreatorToTemplateAction; | |||
import org.sonar.server.permission.ws.template.AddUserToTemplateAction; | |||
@@ -27,12 +32,15 @@ import org.sonar.server.permission.ws.template.ApplyTemplateAction; | |||
import org.sonar.server.permission.ws.template.BulkApplyTemplateAction; | |||
import org.sonar.server.permission.ws.template.CreateTemplateAction; | |||
import org.sonar.server.permission.ws.template.DefaultPermissionTemplateFinder; | |||
import org.sonar.server.permission.ws.template.DeleteTemplateAction; | |||
import org.sonar.server.permission.ws.template.RemoveGroupFromTemplateAction; | |||
import org.sonar.server.permission.ws.template.RemoveProjectCreatorFromTemplateAction; | |||
import org.sonar.server.permission.ws.template.RemoveUserFromTemplateAction; | |||
import org.sonar.server.permission.ws.template.SearchTemplatesAction; | |||
import org.sonar.server.permission.ws.template.SearchTemplatesDataLoader; | |||
import org.sonar.server.permission.ws.template.SetDefaultTemplateAction; | |||
import org.sonar.server.permission.ws.template.TemplateGroupsAction; | |||
import org.sonar.server.permission.ws.template.TemplateUsersAction; | |||
import org.sonar.server.permission.ws.template.UpdateTemplateAction; | |||
public class PermissionsWsModule extends Module { | |||
@@ -65,10 +73,14 @@ public class PermissionsWsModule extends Module { | |||
TemplateGroupsAction.class, | |||
BulkApplyTemplateAction.class, | |||
// utility classes | |||
PermissionChangeBuilder.class, | |||
PermissionRepository.class, | |||
PermissionService.class, | |||
PermissionUpdater.class, | |||
UserPermissionChanger.class, | |||
GroupPermissionChanger.class, | |||
SearchProjectPermissionsDataLoader.class, | |||
SearchTemplatesDataLoader.class, | |||
PermissionDependenciesFinder.class, | |||
PermissionWsSupport.class, | |||
DefaultPermissionTemplateFinder.class); | |||
} | |||
} |
@@ -31,6 +31,7 @@ import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_D | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_GROUP_ID; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_GROUP_NAME; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_ID; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_ORGANIZATION_KEY; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PERMISSION; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PROJECT_ID; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PROJECT_KEY; | |||
@@ -67,15 +68,23 @@ public class PermissionsWsParametersBuilder { | |||
public static NewParam createProjectPermissionParameter(NewAction action) { | |||
return action.createParam(PARAM_PERMISSION) | |||
.setDescription(PROJECT_PERMISSION_PARAM_DESCRIPTION) | |||
.setPossibleValues(ProjectPermissions.ALL) | |||
.setRequired(true); | |||
} | |||
public static void createGroupNameParameter(NewAction action) { | |||
createOrganizationParameter(action); | |||
action.createParam(PARAM_GROUP_NAME) | |||
.setDescription("Group name or 'anyone' (case insensitive)") | |||
.setExampleValue("sonar-administrators"); | |||
} | |||
public static void createOrganizationParameter(NewAction action) { | |||
action.createParam(PARAM_ORGANIZATION_KEY) | |||
.setDescription("Key of organization, used when group name is set") | |||
.setExampleValue("my-org"); | |||
} | |||
public static void createGroupIdParameter(NewAction action) { | |||
action.createParam(PARAM_GROUP_ID) | |||
.setDescription("Group id") |
@@ -19,41 +19,37 @@ | |||
*/ | |||
package org.sonar.server.permission.ws; | |||
import com.google.common.base.Optional; | |||
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; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.server.permission.GroupPermissionChange; | |||
import org.sonar.server.permission.PermissionChange; | |||
import org.sonar.server.permission.PermissionUpdater; | |||
import org.sonarqube.ws.client.permission.RemoveGroupWsRequest; | |||
import org.sonar.server.permission.ProjectRef; | |||
import org.sonar.server.usergroups.ws.GroupIdOrAnyone; | |||
import static org.sonar.server.permission.ws.PermissionRequestValidator.validatePermission; | |||
import static java.util.Arrays.asList; | |||
import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createGroupIdParameter; | |||
import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createGroupNameParameter; | |||
import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createPermissionParameter; | |||
import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createProjectParameters; | |||
import static org.sonar.server.permission.ws.WsProjectRef.newOptionalWsProjectRef; | |||
import static org.sonar.server.usergroups.ws.WsGroupRef.newWsGroupRef; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_GROUP_ID; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_GROUP_NAME; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PERMISSION; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PROJECT_ID; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PROJECT_KEY; | |||
public class RemoveGroupAction implements PermissionsWsAction { | |||
public static final String ACTION = "remove_group"; | |||
private final DbClient dbClient; | |||
private final PermissionChangeBuilder permissionChangeBuilder; | |||
private final PermissionUpdater permissionUpdater; | |||
private final PermissionWsSupport support; | |||
public RemoveGroupAction(DbClient dbClient, PermissionChangeBuilder permissionChangeBuilder, PermissionUpdater permissionUpdater) { | |||
public RemoveGroupAction(DbClient dbClient, PermissionUpdater permissionUpdater, PermissionWsSupport support) { | |||
this.dbClient = dbClient; | |||
this.permissionChangeBuilder = permissionChangeBuilder; | |||
this.permissionUpdater = permissionUpdater; | |||
this.support = support; | |||
} | |||
@Override | |||
@@ -75,33 +71,17 @@ public class RemoveGroupAction implements PermissionsWsAction { | |||
@Override | |||
public void handle(Request request, Response response) throws Exception { | |||
doHandle(toRemoveGroupWsRequest(request)); | |||
response.noContent(); | |||
} | |||
try (DbSession dbSession = dbClient.openSession(false)) { | |||
GroupIdOrAnyone group = support.findGroup(dbSession, request); | |||
Optional<ProjectRef> projectId = support.findProject(dbSession, request); | |||
private void doHandle(RemoveGroupWsRequest request) { | |||
DbSession dbSession = dbClient.openSession(false); | |||
try { | |||
Optional<WsProjectRef> projectRef = newOptionalWsProjectRef(request.getProjectId(), request.getProjectKey()); | |||
Long groupId = request.getGroupId() == null ? null : Long.valueOf(request.getGroupId()); | |||
validatePermission(request.getPermission(), projectRef); | |||
PermissionChange permissionChange = permissionChangeBuilder.buildGroupPermissionChange( | |||
dbSession, | |||
request.getPermission(), | |||
projectRef, | |||
newWsGroupRef(groupId, request.getGroupName())); | |||
permissionUpdater.removePermission(permissionChange); | |||
} finally { | |||
dbClient.closeSession(dbSession); | |||
PermissionChange change = new GroupPermissionChange( | |||
PermissionChange.Operation.REMOVE, | |||
request.mandatoryParam(PARAM_PERMISSION), | |||
projectId.orElse(null), | |||
group); | |||
permissionUpdater.apply(dbSession, asList(change)); | |||
} | |||
} | |||
private static RemoveGroupWsRequest toRemoveGroupWsRequest(Request request) { | |||
return new RemoveGroupWsRequest() | |||
.setPermission(request.mandatoryParam(PARAM_PERMISSION)) | |||
.setGroupId(request.param(PARAM_GROUP_ID)) | |||
.setGroupName(request.param(PARAM_GROUP_NAME)) | |||
.setProjectId(request.param(PARAM_PROJECT_ID)) | |||
.setProjectKey(request.param(PARAM_PROJECT_KEY)); | |||
response.noContent(); | |||
} | |||
} |
@@ -19,24 +19,26 @@ | |||
*/ | |||
package org.sonar.server.permission.ws; | |||
import com.google.common.base.Optional; | |||
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; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.organization.OrganizationDto; | |||
import org.sonar.server.permission.PermissionChange; | |||
import org.sonar.server.permission.PermissionUpdater; | |||
import org.sonarqube.ws.client.permission.RemoveUserWsRequest; | |||
import org.sonar.server.permission.ProjectRef; | |||
import org.sonar.server.permission.UserId; | |||
import org.sonar.server.permission.UserPermissionChange; | |||
import static org.sonar.server.permission.ws.PermissionRequestValidator.validatePermission; | |||
import static java.util.Arrays.asList; | |||
import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createOrganizationParameter; | |||
import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createPermissionParameter; | |||
import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createProjectParameters; | |||
import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createUserLoginParameter; | |||
import static org.sonar.server.permission.ws.WsProjectRef.newOptionalWsProjectRef; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_ORGANIZATION_KEY; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PERMISSION; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PROJECT_ID; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PROJECT_KEY; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_USER_LOGIN; | |||
public class RemoveUserAction implements PermissionsWsAction { | |||
@@ -45,12 +47,12 @@ public class RemoveUserAction implements PermissionsWsAction { | |||
private final DbClient dbClient; | |||
private final PermissionUpdater permissionUpdater; | |||
private final PermissionChangeBuilder permissionChangeBuilder; | |||
private final PermissionWsSupport support; | |||
public RemoveUserAction(DbClient dbClient, PermissionUpdater permissionUpdater, PermissionChangeBuilder permissionChangeBuilder) { | |||
public RemoveUserAction(DbClient dbClient, PermissionUpdater permissionUpdater, PermissionWsSupport support) { | |||
this.dbClient = dbClient; | |||
this.permissionUpdater = permissionUpdater; | |||
this.permissionChangeBuilder = permissionChangeBuilder; | |||
this.support = support; | |||
} | |||
@Override | |||
@@ -66,36 +68,24 @@ public class RemoveUserAction implements PermissionsWsAction { | |||
createPermissionParameter(action); | |||
createUserLoginParameter(action); | |||
createProjectParameters(action); | |||
createOrganizationParameter(action); | |||
} | |||
@Override | |||
public void handle(Request request, Response response) throws Exception { | |||
doHandle(toRemoveUserWsRequest(request)); | |||
response.noContent(); | |||
} | |||
private void doHandle(RemoveUserWsRequest request) { | |||
DbSession dbSession = dbClient.openSession(false); | |||
try { | |||
Optional<WsProjectRef> projectRef = newOptionalWsProjectRef(request.getProjectId(), request.getProjectKey()); | |||
validatePermission(request.getPermission(), projectRef); | |||
PermissionChange permissionChange = permissionChangeBuilder.buildUserPermissionChange( | |||
dbSession, | |||
request.getPermission(), | |||
projectRef, | |||
request.getLogin()); | |||
permissionUpdater.removePermission(permissionChange); | |||
try (DbSession dbSession = dbClient.openSession(false)) { | |||
UserId user = support.findUser(dbSession, request.mandatoryParam(PARAM_USER_LOGIN)); | |||
Optional<ProjectRef> projectId = support.findProject(dbSession, request); | |||
OrganizationDto org = support.findOrganization(dbSession, request.param(PARAM_ORGANIZATION_KEY)); | |||
} finally { | |||
dbClient.closeSession(dbSession); | |||
PermissionChange change = new UserPermissionChange( | |||
PermissionChange.Operation.REMOVE, | |||
org.getUuid(), | |||
request.mandatoryParam(PARAM_PERMISSION), | |||
projectId.orElse(null), | |||
user); | |||
permissionUpdater.apply(dbSession, asList(change)); | |||
response.noContent(); | |||
} | |||
} | |||
private static RemoveUserWsRequest toRemoveUserWsRequest(Request request) { | |||
return new RemoveUserWsRequest() | |||
.setPermission(request.mandatoryParam(PARAM_PERMISSION)) | |||
.setLogin(request.mandatoryParam(PARAM_USER_LOGIN)) | |||
.setProjectId(request.param(PARAM_PROJECT_ID)) | |||
.setProjectKey(request.param(PARAM_PROJECT_KEY)); | |||
} | |||
} |
@@ -64,12 +64,9 @@ public class SearchGlobalPermissionsAction implements PermissionsWsAction { | |||
public void handle(Request wsRequest, Response wsResponse) throws Exception { | |||
checkGlobalAdminUser(userSession); | |||
DbSession dbSession = dbClient.openSession(false); | |||
try { | |||
try (DbSession dbSession = dbClient.openSession(false)) { | |||
WsSearchGlobalPermissionsResponse response = buildResponse(dbSession); | |||
writeProtobuf(response, wsRequest, wsResponse); | |||
} finally { | |||
dbClient.closeSession(dbSession); | |||
} | |||
} | |||
@@ -30,7 +30,6 @@ import org.sonar.api.server.ws.WebService.Param; | |||
import org.sonar.api.utils.Paging; | |||
import org.sonar.core.permission.ProjectPermissions; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.component.ComponentDto; | |||
import org.sonar.server.user.UserSession; | |||
import org.sonarqube.ws.Common; | |||
@@ -99,14 +98,9 @@ public class SearchProjectPermissionsAction implements PermissionsWsAction { | |||
private SearchProjectPermissionsWsResponse doHandle(SearchProjectPermissionsWsRequest request) { | |||
checkRequestAndPermissions(request); | |||
DbSession dbSession = dbClient.openSession(false); | |||
try { | |||
validateQualifier(request.getQualifier(), resourceTypes); | |||
SearchProjectPermissionsData data = dataLoader.load(request); | |||
return buildResponse(data); | |||
} finally { | |||
dbClient.closeSession(dbSession); | |||
} | |||
validateQualifier(request.getQualifier(), resourceTypes); | |||
SearchProjectPermissionsData data = dataLoader.load(request); | |||
return buildResponse(data); | |||
} | |||
private static SearchProjectPermissionsWsRequest toSearchProjectPermissionsWsRequest(Request request) { |
@@ -70,9 +70,8 @@ class SearchProjectPermissionsData { | |||
return FluentIterable.from( | |||
Iterables.concat( | |||
userCountByProjectIdAndPermission.row(rootComponentId).keySet(), | |||
groupCountByProjectIdAndPermission.row(rootComponentId).keySet() | |||
) | |||
).toSortedSet(Ordering.natural()); | |||
groupCountByProjectIdAndPermission.row(rootComponentId).keySet())) | |||
.toSortedSet(Ordering.natural()); | |||
} | |||
static class Builder { |
@@ -43,18 +43,17 @@ import static org.sonar.server.permission.ws.WsProjectRef.newOptionalWsProjectRe | |||
public class SearchProjectPermissionsDataLoader { | |||
private final DbClient dbClient; | |||
private final PermissionDependenciesFinder finder; | |||
private final PermissionWsSupport wsSupport; | |||
private final String[] rootQualifiers; | |||
public SearchProjectPermissionsDataLoader(DbClient dbClient, PermissionDependenciesFinder finder, ResourceTypes resourceTypes) { | |||
public SearchProjectPermissionsDataLoader(DbClient dbClient, PermissionWsSupport wsSupport, ResourceTypes resourceTypes) { | |||
this.dbClient = dbClient; | |||
this.finder = finder; | |||
this.wsSupport = wsSupport; | |||
this.rootQualifiers = Collections2.transform(resourceTypes.getRoots(), RESOURCE_TYPE_TO_QUALIFIER).toArray(new String[resourceTypes.getRoots().size()]); | |||
} | |||
SearchProjectPermissionsData load(SearchProjectPermissionsWsRequest request) { | |||
DbSession dbSession = dbClient.openSession(false); | |||
try { | |||
try (DbSession dbSession = dbClient.openSession(false)) { | |||
SearchProjectPermissionsData.Builder data = newBuilder(); | |||
int countRootComponents = countRootComponents(dbSession, request); | |||
List<ComponentDto> rootComponents = searchRootComponents(dbSession, request, paging(request, countRootComponents)); | |||
@@ -66,8 +65,6 @@ public class SearchProjectPermissionsDataLoader { | |||
.groupCountByProjectIdAndPermission(groupCountByRootComponentIdAndPermission(dbSession, rootComponentIds)); | |||
return data.build(); | |||
} finally { | |||
dbClient.closeSession(dbSession); | |||
} | |||
} | |||
@@ -85,7 +82,7 @@ public class SearchProjectPermissionsDataLoader { | |||
Optional<WsProjectRef> project = newOptionalWsProjectRef(request.getProjectId(), request.getProjectKey()); | |||
if (project.isPresent()) { | |||
return singletonList(finder.getRootComponentOrModule(dbSession, project.get())); | |||
return singletonList(wsSupport.getRootComponentOrModule(dbSession, project.get())); | |||
} | |||
return dbClient.componentDao().selectByQuery(dbSession, toDbQuery(request), paging.offset(), paging.pageSize()); |
@@ -19,11 +19,11 @@ | |||
*/ | |||
package org.sonar.server.permission.ws; | |||
import com.google.common.base.Optional; | |||
import com.google.common.collect.Multimap; | |||
import com.google.common.collect.Ordering; | |||
import com.google.common.collect.TreeMultimap; | |||
import java.util.List; | |||
import java.util.Optional; | |||
import java.util.stream.Collectors; | |||
import org.sonar.api.server.ws.Request; | |||
import org.sonar.api.server.ws.Response; | |||
@@ -32,40 +32,37 @@ import org.sonar.api.server.ws.WebService.Param; | |||
import org.sonar.api.utils.Paging; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.component.ComponentDto; | |||
import org.sonar.db.permission.ExtendedUserPermissionDto; | |||
import org.sonar.db.permission.PermissionQuery; | |||
import org.sonar.db.user.UserDto; | |||
import org.sonar.server.permission.ProjectRef; | |||
import org.sonar.server.user.UserSession; | |||
import org.sonarqube.ws.WsPermissions; | |||
import org.sonarqube.ws.WsPermissions.UsersWsResponse; | |||
import org.sonarqube.ws.client.permission.UsersWsRequest; | |||
import static java.util.Collections.emptyList; | |||
import static org.sonar.db.permission.PermissionQuery.DEFAULT_PAGE_SIZE; | |||
import static org.sonar.db.permission.PermissionQuery.RESULTS_MAX_SIZE; | |||
import static org.sonar.db.permission.PermissionQuery.SEARCH_QUERY_MIN_LENGTH; | |||
import static org.sonar.server.permission.PermissionPrivilegeChecker.checkProjectAdminUserByComponentDto; | |||
import static org.sonar.server.permission.ws.PermissionRequestValidator.validatePermission; | |||
import static org.sonar.server.permission.PermissionPrivilegeChecker.checkProjectAdminUserByComponentUuid; | |||
import static org.sonar.server.permission.ws.PermissionRequestValidator.validateGlobalPermission; | |||
import static org.sonar.server.permission.ws.PermissionRequestValidator.validateProjectPermission; | |||
import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createPermissionParameter; | |||
import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createProjectParameters; | |||
import static org.sonar.server.permission.ws.WsProjectRef.newOptionalWsProjectRef; | |||
import static org.sonar.server.ws.WsUtils.checkRequest; | |||
import static org.sonar.server.ws.WsUtils.writeProtobuf; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PERMISSION; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PROJECT_ID; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PROJECT_KEY; | |||
public class UsersAction implements PermissionsWsAction { | |||
private final DbClient dbClient; | |||
private final UserSession userSession; | |||
private final PermissionDependenciesFinder dependenciesFinder; | |||
private final PermissionWsSupport support; | |||
public UsersAction(DbClient dbClient, UserSession userSession, PermissionDependenciesFinder dependenciesFinder) { | |||
public UsersAction(DbClient dbClient, UserSession userSession, PermissionWsSupport support) { | |||
this.dbClient = dbClient; | |||
this.userSession = userSession; | |||
this.dependenciesFinder = dependenciesFinder; | |||
this.support = support; | |||
} | |||
@Override | |||
@@ -90,42 +87,46 @@ public class UsersAction implements PermissionsWsAction { | |||
} | |||
@Override | |||
public void handle(Request wsRequest, Response wsResponse) throws Exception { | |||
UsersWsResponse usersWsResponse = doHandle(toUsersWsRequest(wsRequest)); | |||
writeProtobuf(usersWsResponse, wsRequest, wsResponse); | |||
} | |||
private UsersWsResponse doHandle(UsersWsRequest request) { | |||
Optional<WsProjectRef> wsProjectRef = newOptionalWsProjectRef(request.getProjectId(), request.getProjectKey()); | |||
validatePermission(request.getPermission(), wsProjectRef); | |||
DbSession dbSession = dbClient.openSession(false); | |||
try { | |||
Optional<ComponentDto> project = dependenciesFinder.searchProject(dbSession, wsProjectRef); | |||
checkProjectAdminUserByComponentDto(userSession, project); | |||
PermissionQuery dbQuery = buildPermissionQuery(request, project); | |||
List<UserDto> users = findUsers(dbSession, dbQuery); | |||
int total = dbClient.userPermissionDao().countUsers(dbSession, dbQuery); | |||
List<ExtendedUserPermissionDto> userPermissions = findUserPermissions(dbSession, users, project); | |||
Paging paging = Paging.forPageIndex(request.getPage()).withPageSize(request.getPageSize()).andTotal(total); | |||
return buildResponse(users, userPermissions, paging); | |||
} finally { | |||
dbClient.closeSession(dbSession); | |||
public void handle(Request request, Response response) throws Exception { | |||
try (DbSession dbSession = dbClient.openSession(false)) { | |||
Optional<ProjectRef> projectId = support.findProject(dbSession, request); | |||
checkProjectAdminUserByComponentUuid(userSession, projectId.isPresent() ? projectId.get().getUuid() : null); | |||
PermissionQuery query = buildPermissionQuery(request, projectId); | |||
List<UserDto> users = findUsers(dbSession, query); | |||
int total = dbClient.userPermissionDao().countUsers(dbSession, query); | |||
List<ExtendedUserPermissionDto> userPermissions = findUserPermissions(dbSession, users, projectId); | |||
Paging paging = Paging.forPageIndex(request.mandatoryParamAsInt(Param.PAGE)).withPageSize(query.getPageSize()).andTotal(total); | |||
UsersWsResponse usersWsResponse = buildResponse(users, userPermissions, paging); | |||
writeProtobuf(usersWsResponse, request, response); | |||
} | |||
} | |||
private static UsersWsRequest toUsersWsRequest(Request request) { | |||
UsersWsRequest usersRequest = new UsersWsRequest() | |||
.setPermission(request.param(PARAM_PERMISSION)) | |||
.setProjectId(request.param(PARAM_PROJECT_ID)) | |||
.setProjectKey(request.param(PARAM_PROJECT_KEY)) | |||
.setQuery(request.param(Param.TEXT_QUERY)) | |||
.setPage(request.mandatoryParamAsInt(Param.PAGE)) | |||
.setPageSize(request.mandatoryParamAsInt(Param.PAGE_SIZE)); | |||
String searchQuery = usersRequest.getQuery(); | |||
checkRequest(searchQuery == null || searchQuery.length() >= SEARCH_QUERY_MIN_LENGTH, | |||
"The '%s' parameter must have at least %d characters", Param.TEXT_QUERY, SEARCH_QUERY_MIN_LENGTH); | |||
return usersRequest; | |||
private static PermissionQuery buildPermissionQuery(Request request, Optional<ProjectRef> project) { | |||
String textQuery = request.param(Param.TEXT_QUERY); | |||
String permission = request.param(PARAM_PERMISSION); | |||
PermissionQuery.Builder permissionQuery = PermissionQuery.builder() | |||
.setPermission(permission) | |||
.setPageIndex(request.mandatoryParamAsInt(Param.PAGE)) | |||
.setPageSize(request.mandatoryParamAsInt(Param.PAGE_SIZE)) | |||
.setSearchQuery(textQuery); | |||
if (project.isPresent()) { | |||
permissionQuery.setComponentUuid(project.get().getUuid()); | |||
} | |||
if (permission != null) { | |||
if (project.isPresent()) { | |||
validateProjectPermission(permission); | |||
} else { | |||
validateGlobalPermission(permission); | |||
} | |||
} | |||
if (textQuery == null) { | |||
permissionQuery.withAtLeastOnePermission(); | |||
} else { | |||
checkRequest(textQuery.length() >= SEARCH_QUERY_MIN_LENGTH, | |||
"The '%s' parameter must have at least %d characters", Param.TEXT_QUERY, SEARCH_QUERY_MIN_LENGTH); | |||
} | |||
return permissionQuery.build(); | |||
} | |||
private static UsersWsResponse buildResponse(List<UserDto> users, List<ExtendedUserPermissionDto> userPermissions, Paging paging) { | |||
@@ -155,34 +156,18 @@ public class UsersAction implements PermissionsWsAction { | |||
return response.build(); | |||
} | |||
private static PermissionQuery buildPermissionQuery(UsersWsRequest request, Optional<ComponentDto> project) { | |||
PermissionQuery.Builder dbQuery = PermissionQuery.builder() | |||
.setPermission(request.getPermission()) | |||
.setPageIndex(request.getPage()) | |||
.setPageSize(request.getPageSize()) | |||
.setSearchQuery(request.getQuery()); | |||
if (project.isPresent()) { | |||
dbQuery.setComponentUuid(project.get().uuid()); | |||
} | |||
if (request.getQuery() == null) { | |||
dbQuery.withAtLeastOnePermission(); | |||
} | |||
return dbQuery.build(); | |||
} | |||
private List<UserDto> findUsers(DbSession dbSession, PermissionQuery dbQuery) { | |||
List<String> orderedLogins = dbClient.userPermissionDao().selectLogins(dbSession, dbQuery); | |||
private List<UserDto> findUsers(DbSession dbSession, PermissionQuery query) { | |||
List<String> orderedLogins = dbClient.userPermissionDao().selectLogins(dbSession, query); | |||
return Ordering.explicit(orderedLogins).onResultOf(UserDto::getLogin).immutableSortedCopy(dbClient.userDao().selectByLogins(dbSession, orderedLogins)); | |||
} | |||
private List<ExtendedUserPermissionDto> findUserPermissions(DbSession dbSession, List<UserDto> users, Optional<ComponentDto> project) { | |||
private List<ExtendedUserPermissionDto> findUserPermissions(DbSession dbSession, List<UserDto> users, Optional<ProjectRef> project) { | |||
if (users.isEmpty()) { | |||
return emptyList(); | |||
} | |||
List<String> logins = users.stream().map(UserDto::getLogin).collect(Collectors.toList()); | |||
PermissionQuery query = PermissionQuery.builder() | |||
.setComponentUuid(project.isPresent() ? project.get().uuid() : null) | |||
.setComponentUuid(project.isPresent() ? project.get().getUuid() : null) | |||
.withAtLeastOnePermission() | |||
.build(); | |||
return dbClient.userPermissionDao().select(dbSession, query, logins); |
@@ -29,7 +29,7 @@ import static org.sonar.server.ws.WsUtils.checkRequest; | |||
* Project identifiers from a WS request. Guaranties the project id and project key are not provided at the same time. | |||
*/ | |||
public class WsProjectRef { | |||
private static final String MSG_ID_OR_KEY_MUST_BE_PROVIDED = "Project id or project key must be provided, not both."; | |||
private static final String MSG_ID_OR_KEY_MUST_BE_PROVIDED = "Project id or project key can be provided, not both."; | |||
private final String uuid; | |||
private final String key; | |||
@@ -33,7 +33,6 @@ import org.sonar.ce.CeModule; | |||
import org.sonar.ce.settings.ProjectSettingsFactory; | |||
import org.sonar.core.component.DefaultResourceTypes; | |||
import org.sonar.core.timemachine.Periods; | |||
import org.sonar.db.permission.PermissionRepository; | |||
import org.sonar.server.authentication.AuthenticationModule; | |||
import org.sonar.server.batch.BatchWsModule; | |||
import org.sonar.server.ce.ws.CeWsModule; | |||
@@ -136,8 +135,6 @@ import org.sonar.server.notification.NotificationService; | |||
import org.sonar.server.notification.email.AlertsEmailTemplate; | |||
import org.sonar.server.notification.email.EmailNotificationChannel; | |||
import org.sonar.server.organization.ws.OrganizationsWsModule; | |||
import org.sonar.server.permission.PermissionService; | |||
import org.sonar.server.permission.PermissionUpdater; | |||
import org.sonar.server.permission.ws.PermissionsWsModule; | |||
import org.sonar.server.platform.BackendCleanup; | |||
import org.sonar.server.platform.PersistentSettings; | |||
@@ -428,9 +425,6 @@ public class PlatformLevel4 extends PlatformLevel { | |||
UserGroupsModule.class, | |||
// permissions | |||
PermissionRepository.class, | |||
PermissionService.class, | |||
PermissionUpdater.class, | |||
PermissionsWsModule.class, | |||
// components |
@@ -19,6 +19,9 @@ | |||
*/ | |||
package org.sonar.server.startup; | |||
import java.util.Date; | |||
import java.util.Optional; | |||
import javax.annotation.Nullable; | |||
import org.sonar.api.resources.Qualifiers; | |||
import org.sonar.api.security.DefaultGroups; | |||
import org.sonar.api.utils.log.Logger; | |||
@@ -30,9 +33,11 @@ import org.sonar.db.DbSession; | |||
import org.sonar.db.loadedtemplate.LoadedTemplateDto; | |||
import org.sonar.db.permission.template.PermissionTemplateDto; | |||
import org.sonar.db.user.GroupDto; | |||
import org.sonar.server.permission.DefaultPermissionTemplates; | |||
import org.sonar.server.organization.DefaultOrganizationProvider; | |||
import org.sonar.server.platform.PersistentSettings; | |||
import static org.sonar.db.loadedtemplate.LoadedTemplateDto.PERMISSION_TEMPLATE_TYPE; | |||
import static org.sonar.server.permission.DefaultPermissionTemplates.DEFAULT_TEMPLATE_KEY; | |||
import static org.sonar.server.permission.DefaultPermissionTemplates.DEFAULT_TEMPLATE_PROPERTY; | |||
import static org.sonar.server.permission.DefaultPermissionTemplates.defaultRootQualifierTemplateProperty; | |||
@@ -42,10 +47,12 @@ public class RegisterPermissionTemplates { | |||
private final DbClient dbClient; | |||
private final PersistentSettings settings; | |||
private final DefaultOrganizationProvider defaultOrganizationProvider; | |||
public RegisterPermissionTemplates(DbClient dbClient, PersistentSettings settings) { | |||
public RegisterPermissionTemplates(DbClient dbClient, PersistentSettings settings, DefaultOrganizationProvider defaultOrganizationProvider) { | |||
this.dbClient = dbClient; | |||
this.settings = settings; | |||
this.defaultOrganizationProvider = defaultOrganizationProvider; | |||
} | |||
public void start() { | |||
@@ -57,8 +64,8 @@ public class RegisterPermissionTemplates { | |||
String defaultProjectPermissionTemplateUuid = settings.getString(defaultRootQualifierTemplateProperty(Qualifiers.PROJECT)); | |||
setDefaultProperty(defaultProjectPermissionTemplateUuid); | |||
} else if (shouldRegister) { | |||
insertDefaultTemplate(); | |||
setDefaultProperty(DefaultPermissionTemplates.DEFAULT_TEMPLATE.getUuid()); | |||
PermissionTemplateDto template = insertDefaultTemplate(); | |||
setDefaultProperty(template.getUuid()); | |||
} | |||
if (shouldRegister) { | |||
@@ -73,43 +80,50 @@ public class RegisterPermissionTemplates { | |||
} | |||
private boolean shouldRegister() { | |||
return dbClient.loadedTemplateDao().countByTypeAndKey(LoadedTemplateDto.PERMISSION_TEMPLATE_TYPE, DefaultPermissionTemplates.DEFAULT_TEMPLATE.getUuid()) == 0; | |||
return dbClient.loadedTemplateDao().countByTypeAndKey(PERMISSION_TEMPLATE_TYPE, DEFAULT_TEMPLATE_KEY) == 0; | |||
} | |||
private void insertDefaultTemplate() { | |||
DbSession dbSession = dbClient.openSession(false); | |||
try { | |||
PermissionTemplateDto defaultPermissionTemplate = dbClient.permissionTemplateDao().insert(dbSession, DefaultPermissionTemplates.DEFAULT_TEMPLATE); | |||
addGroupPermission(defaultPermissionTemplate, UserRole.ADMIN, DefaultGroups.ADMINISTRATORS); | |||
addGroupPermission(defaultPermissionTemplate, UserRole.ISSUE_ADMIN, DefaultGroups.ADMINISTRATORS); | |||
addGroupPermission(defaultPermissionTemplate, UserRole.USER, DefaultGroups.ANYONE); | |||
addGroupPermission(defaultPermissionTemplate, UserRole.CODEVIEWER, DefaultGroups.ANYONE); | |||
} finally { | |||
dbClient.closeSession(dbSession); | |||
private PermissionTemplateDto insertDefaultTemplate() { | |||
try (DbSession dbSession = dbClient.openSession(false)) { | |||
String orgUuid = defaultOrganizationProvider.get().getUuid(); | |||
PermissionTemplateDto template = new PermissionTemplateDto() | |||
.setOrganizationUuid(orgUuid) | |||
.setName("Default template") | |||
.setUuid(DEFAULT_TEMPLATE_KEY) | |||
.setDescription("This permission template will be used as default when no other permission configuration is available") | |||
.setCreatedAt(new Date()) | |||
.setUpdatedAt(new Date()); | |||
dbClient.permissionTemplateDao().insert(dbSession, template); | |||
insertDefaultGroupPermissions(dbSession, template); | |||
dbSession.commit(); | |||
return template; | |||
} | |||
} | |||
private void addGroupPermission(PermissionTemplateDto template, String permission, String groupName) { | |||
DbSession dbSession = dbClient.openSession(false); | |||
try { | |||
Long groupId = null; | |||
if (!DefaultGroups.isAnyone(groupName)) { | |||
GroupDto groupDto = dbClient.groupDao().selectByName(dbSession, groupName); | |||
if (groupDto != null) { | |||
groupId = groupDto.getId(); | |||
} else { | |||
LOG.error("Cannot setup default permission for group: " + groupName); | |||
} | |||
} | |||
dbClient.permissionTemplateDao().insertGroupPermission(dbSession, template.getId(), groupId, permission); | |||
} finally { | |||
dbClient.closeSession(dbSession); | |||
private void insertDefaultGroupPermissions(DbSession dbSession, PermissionTemplateDto template) { | |||
Optional<GroupDto> admins = dbClient.groupDao().selectByName(dbSession, template.getOrganizationUuid(), DefaultGroups.ADMINISTRATORS); | |||
if (admins.isPresent()) { | |||
insertGroupPermission(dbSession, template, UserRole.ADMIN, admins.get()); | |||
insertGroupPermission(dbSession, template, UserRole.ISSUE_ADMIN, admins.get()); | |||
} else { | |||
LOG.error("Cannot setup default permission for group: " + DefaultGroups.ADMINISTRATORS); | |||
} | |||
insertGroupPermission(dbSession, template, UserRole.USER, null); | |||
insertGroupPermission(dbSession, template, UserRole.CODEVIEWER, null); | |||
} | |||
private void insertGroupPermission(DbSession dbSession, PermissionTemplateDto template, String permission, @Nullable GroupDto group) { | |||
if (group == null) { | |||
dbClient.permissionTemplateDao().insertGroupPermission(dbSession, template.getId(), null, permission); | |||
} else { | |||
dbClient.permissionTemplateDao().insertGroupPermission(dbSession, template.getId(), group.getId(), permission); | |||
} | |||
} | |||
private void registerInitialization() { | |||
LoadedTemplateDto loadedTemplate = new LoadedTemplateDto(DefaultPermissionTemplates.DEFAULT_TEMPLATE.getUuid(), | |||
LoadedTemplateDto.PERMISSION_TEMPLATE_TYPE); | |||
LoadedTemplateDto loadedTemplate = new LoadedTemplateDto(DEFAULT_TEMPLATE_KEY, PERMISSION_TEMPLATE_TYPE); | |||
dbClient.loadedTemplateDao().insert(loadedTemplate); | |||
} | |||
@@ -1,10 +1,7 @@ | |||
{ | |||
"permissionTemplate": { | |||
"id": "af8cb8cc-1e78-4c4e-8c00-ee8e814009a5", | |||
"name": "Finance", | |||
"description": "Permissions for financially related projects", | |||
"projectKeyPattern": ".*\\.finance\\..*", | |||
"createdAt": "2015-08-25T16:18:48+0200", | |||
"updatedAt": "2015-08-25T16:18:48+0200" | |||
"projectKeyPattern": ".*\\.finance\\..*" | |||
} | |||
} |
@@ -0,0 +1,218 @@ | |||
/* | |||
* 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.permission; | |||
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.api.web.UserRole; | |||
import org.sonar.core.permission.GlobalPermissions; | |||
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.organization.OrganizationDto; | |||
import org.sonar.db.organization.OrganizationTesting; | |||
import org.sonar.db.user.GroupDto; | |||
import org.sonar.server.exceptions.BadRequestException; | |||
import org.sonar.server.exceptions.ForbiddenException; | |||
import org.sonar.server.tester.UserSessionRule; | |||
import org.sonar.server.usergroups.ws.GroupIdOrAnyone; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN; | |||
public class GroupPermissionChangerTest { | |||
@Rule | |||
public DbTester db = DbTester.create(System2.INSTANCE); | |||
@Rule | |||
public ExpectedException expectedException = ExpectedException.none(); | |||
private UserSessionRule userSession = UserSessionRule.standalone(); | |||
private GroupPermissionChanger underTest = new GroupPermissionChanger(db.getDbClient(), userSession); | |||
private OrganizationDto org; | |||
private GroupDto group; | |||
private ComponentDto project; | |||
@Before | |||
public void setUp() throws Exception { | |||
org = OrganizationTesting.insert(db, OrganizationTesting.newOrganizationDto()); | |||
group = db.users().insertGroup(org, "a-group"); | |||
project = new ComponentDbTester(db).insertComponent(ComponentTesting.newProjectDto()); | |||
} | |||
@Test | |||
public void add_permission_to_group() { | |||
GroupIdOrAnyone groupId = new GroupIdOrAnyone(group); | |||
loginAsAdmin(); | |||
apply(new GroupPermissionChange(PermissionChange.Operation.ADD, GlobalPermissions.QUALITY_GATE_ADMIN, null, groupId)); | |||
assertThat(db.users().selectGroupPermissions(group, null)).containsOnly(GlobalPermissions.QUALITY_GATE_ADMIN); | |||
} | |||
@Test | |||
public void add_project_permission_to_group() { | |||
GroupIdOrAnyone groupId = new GroupIdOrAnyone(group); | |||
loginAsAdmin(); | |||
apply(new GroupPermissionChange(PermissionChange.Operation.ADD, UserRole.ISSUE_ADMIN, new ProjectRef(project), groupId)); | |||
assertThat(db.users().selectGroupPermissions(group, null)).isEmpty(); | |||
assertThat(db.users().selectGroupPermissions(group, project)).containsOnly(UserRole.ISSUE_ADMIN); | |||
} | |||
@Test | |||
public void add_permission_to_anyone() { | |||
GroupIdOrAnyone groupId = new GroupIdOrAnyone(db.getDefaultOrganization().getUuid(), null); | |||
loginAsAdmin(); | |||
apply(new GroupPermissionChange(PermissionChange.Operation.ADD, GlobalPermissions.QUALITY_GATE_ADMIN, null, groupId)); | |||
assertThat(db.users().selectGroupPermissions(group, null)).isEmpty(); | |||
assertThat(db.users().selectAnyonePermissions(null)).containsOnly(GlobalPermissions.QUALITY_GATE_ADMIN); | |||
} | |||
@Test | |||
public void add_project_permission_to_anyone() { | |||
GroupIdOrAnyone groupId = new GroupIdOrAnyone(db.getDefaultOrganization().getUuid(), null); | |||
loginAsAdmin(); | |||
apply(new GroupPermissionChange(PermissionChange.Operation.ADD, UserRole.ISSUE_ADMIN, new ProjectRef(project), groupId)); | |||
assertThat(db.users().selectAnyonePermissions(null)).isEmpty(); | |||
assertThat(db.users().selectAnyonePermissions(project)).containsOnly(UserRole.ISSUE_ADMIN); | |||
} | |||
@Test | |||
public void fail_to_add_permission_if_not_admin() { | |||
GroupIdOrAnyone groupId = new GroupIdOrAnyone(db.getDefaultOrganization().getUuid(), null); | |||
expectedException.expect(ForbiddenException.class); | |||
userSession.login("a_guy"); | |||
underTest.apply(db.getSession(), new GroupPermissionChange(PermissionChange.Operation.ADD, UserRole.ISSUE_ADMIN, new ProjectRef(project), groupId)); | |||
} | |||
@Test | |||
public void do_nothing_when_adding_permission_that_already_exists() { | |||
GroupIdOrAnyone groupId = new GroupIdOrAnyone(group); | |||
db.users().insertPermissionOnGroup(group, GlobalPermissions.QUALITY_GATE_ADMIN); | |||
loginAsAdmin(); | |||
apply(new GroupPermissionChange(PermissionChange.Operation.ADD, GlobalPermissions.QUALITY_GATE_ADMIN, null, groupId)); | |||
assertThat(db.users().selectGroupPermissions(group, null)).containsOnly(GlobalPermissions.QUALITY_GATE_ADMIN); | |||
} | |||
@Test | |||
public void fail_to_add_global_permission_on_project() { | |||
GroupIdOrAnyone groupId = new GroupIdOrAnyone(group); | |||
expectedException.expect(BadRequestException.class); | |||
expectedException.expectMessage("Invalid project permission 'gateadmin'. Valid values are [admin, codeviewer, issueadmin, scan, user]"); | |||
loginAsAdmin(); | |||
apply(new GroupPermissionChange(PermissionChange.Operation.ADD, GlobalPermissions.QUALITY_GATE_ADMIN, new ProjectRef(project), groupId)); | |||
} | |||
@Test | |||
public void fail_to_add_project_permission_on_global_group() { | |||
GroupIdOrAnyone groupId = new GroupIdOrAnyone(group); | |||
expectedException.expect(BadRequestException.class); | |||
expectedException.expectMessage("Invalid global permission 'issueadmin'. Valid values are [admin, profileadmin, gateadmin, scan, provisioning]"); | |||
loginAsAdmin(); | |||
apply(new GroupPermissionChange(PermissionChange.Operation.ADD, UserRole.ISSUE_ADMIN, null, groupId)); | |||
} | |||
@Test | |||
public void remove_permission_from_group() { | |||
GroupIdOrAnyone groupId = new GroupIdOrAnyone(group); | |||
db.users().insertPermissionOnGroup(group, GlobalPermissions.QUALITY_GATE_ADMIN); | |||
db.users().insertPermissionOnGroup(group, GlobalPermissions.PROVISIONING); | |||
loginAsAdmin(); | |||
apply(new GroupPermissionChange(PermissionChange.Operation.REMOVE, GlobalPermissions.QUALITY_GATE_ADMIN, null, groupId)); | |||
assertThat(db.users().selectGroupPermissions(group, null)).containsOnly(GlobalPermissions.PROVISIONING); | |||
} | |||
@Test | |||
public void remove_project_permission_from_group() { | |||
GroupIdOrAnyone groupId = new GroupIdOrAnyone(group); | |||
db.users().insertPermissionOnGroup(group, GlobalPermissions.QUALITY_GATE_ADMIN); | |||
db.users().insertProjectPermissionOnGroup(group, UserRole.ISSUE_ADMIN, project); | |||
db.users().insertProjectPermissionOnGroup(group, UserRole.CODEVIEWER, project); | |||
loginAsAdmin(); | |||
apply(new GroupPermissionChange(PermissionChange.Operation.REMOVE, UserRole.ISSUE_ADMIN, new ProjectRef(project), groupId)); | |||
assertThat(db.users().selectGroupPermissions(group, null)).containsOnly(GlobalPermissions.QUALITY_GATE_ADMIN); | |||
assertThat(db.users().selectGroupPermissions(group, project)).containsOnly(UserRole.CODEVIEWER); | |||
} | |||
@Test | |||
public void do_not_fail_if_removing_a_permission_that_does_not_exist() { | |||
GroupIdOrAnyone groupId = new GroupIdOrAnyone(group); | |||
loginAsAdmin(); | |||
apply(new GroupPermissionChange(PermissionChange.Operation.REMOVE, UserRole.ISSUE_ADMIN, new ProjectRef(project), groupId)); | |||
assertThat(db.users().selectGroupPermissions(group, null)).isEmpty(); | |||
assertThat(db.users().selectGroupPermissions(group, project)).isEmpty(); | |||
} | |||
@Test | |||
public void fail_to_remove_permission_if_not_admin() { | |||
GroupIdOrAnyone groupId = new GroupIdOrAnyone(db.getDefaultOrganization().getUuid(), null); | |||
expectedException.expect(ForbiddenException.class); | |||
userSession.login("a_guy"); | |||
underTest.apply(db.getSession(), new GroupPermissionChange(PermissionChange.Operation.REMOVE, UserRole.ISSUE_ADMIN, new ProjectRef(project), groupId)); | |||
} | |||
@Test | |||
public void fail_to_remove_sysadmin_permission_if_no_more_sysadmins() { | |||
GroupIdOrAnyone groupId = new GroupIdOrAnyone(group); | |||
db.users().insertPermissionOnGroup(group, GlobalPermissions.SYSTEM_ADMIN); | |||
expectedException.expect(BadRequestException.class); | |||
expectedException.expectMessage("Last group with 'admin' permission. Permission cannot be removed."); | |||
loginAsAdmin(); | |||
underTest.apply(db.getSession(), new GroupPermissionChange(PermissionChange.Operation.REMOVE, GlobalPermissions.SYSTEM_ADMIN, null, groupId)); | |||
} | |||
private void apply(GroupPermissionChange change) { | |||
underTest.apply(db.getSession(), change); | |||
db.commit(); | |||
} | |||
private void loginAsAdmin() { | |||
userSession.login("admin").setGlobalPermissions(SYSTEM_ADMIN); | |||
} | |||
} |
@@ -1,137 +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.permission; | |||
import com.google.common.collect.Maps; | |||
import java.util.Map; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.ExpectedException; | |||
import org.sonar.core.permission.GlobalPermissions; | |||
import org.sonar.server.exceptions.BadRequestException; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
public class PermissionChangeTest { | |||
@Rule | |||
public ExpectedException thrown = ExpectedException.none(); | |||
@Test | |||
public void populate_from_params() { | |||
Map<String, Object> params = Maps.newHashMap(); | |||
params.put("user", "my_login"); | |||
params.put("group", "my_group"); | |||
params.put("component", "org.sample.Sample"); | |||
params.put("permission", GlobalPermissions.SYSTEM_ADMIN); | |||
PermissionChange query = PermissionChange.buildFromParams(params); | |||
assertThat(query.userLogin()).isEqualTo("my_login"); | |||
assertThat(query.groupName()).isEqualTo("my_group"); | |||
assertThat(query.componentKey()).isEqualTo("org.sample.Sample"); | |||
assertThat(query.permission()).isEqualTo(GlobalPermissions.SYSTEM_ADMIN); | |||
} | |||
@Test | |||
public void validate_user_query() { | |||
Map<String, Object> validUserParams = Maps.newHashMap(); | |||
validUserParams.put("user", "my_login"); | |||
validUserParams.put("permission", GlobalPermissions.SYSTEM_ADMIN); | |||
PermissionChange query = PermissionChange.buildFromParams(validUserParams); | |||
query.validate(); | |||
} | |||
@Test | |||
public void validate_group_query() { | |||
Map<String, Object> validGroupParams = Maps.newHashMap(); | |||
validGroupParams.put("group", "my_group"); | |||
validGroupParams.put("permission", GlobalPermissions.SYSTEM_ADMIN); | |||
PermissionChange query = PermissionChange.buildFromParams(validGroupParams); | |||
query.validate(); | |||
} | |||
@Test | |||
public void reject_inconsistent_query() { | |||
Map<String, Object> inconsistentParams = Maps.newHashMap(); | |||
inconsistentParams.put("user", "my_login"); | |||
inconsistentParams.put("group", "my_group"); | |||
inconsistentParams.put("permission", GlobalPermissions.SYSTEM_ADMIN); | |||
PermissionChange query = PermissionChange.buildFromParams(inconsistentParams); | |||
thrown.expect(BadRequestException.class); | |||
thrown.expectMessage("Only one of user or group parameter should be provided"); | |||
query.validate(); | |||
} | |||
@Test | |||
public void detect_missing_user_or_group() { | |||
Map<String, Object> inconsistentParams = Maps.newHashMap(); | |||
inconsistentParams.put("permission", "admin"); | |||
PermissionChange query = PermissionChange.buildFromParams(inconsistentParams); | |||
thrown.expect(BadRequestException.class); | |||
thrown.expectMessage("Missing user or group parameter"); | |||
query.validate(); | |||
} | |||
@Test | |||
public void detect_missing_permission() { | |||
Map<String, Object> inconsistentParams = Maps.newHashMap(); | |||
inconsistentParams.put("user", "my_login"); | |||
PermissionChange query = PermissionChange.buildFromParams(inconsistentParams); | |||
thrown.expect(BadRequestException.class); | |||
thrown.expectMessage("Missing permission parameter"); | |||
query.validate(); | |||
} | |||
@Test | |||
public void validate_global_permission_reference() { | |||
Map<String, Object> inconsistentParams = Maps.newHashMap(); | |||
inconsistentParams.put("user", "my_login"); | |||
inconsistentParams.put("permission", "invalid"); | |||
PermissionChange query = PermissionChange.buildFromParams(inconsistentParams); | |||
thrown.expect(BadRequestException.class); | |||
thrown.expectMessage("Invalid global permission key invalid. Valid values are [admin, profileadmin, gateadmin, scan, provisioning]"); | |||
query.validate(); | |||
} | |||
@Test | |||
public void validate_component_permission_reference() { | |||
Map<String, Object> inconsistentParams = Maps.newHashMap(); | |||
inconsistentParams.put("user", "my_login"); | |||
inconsistentParams.put("component", "org.sample.Sample"); | |||
inconsistentParams.put("permission", "invalid"); | |||
PermissionChange query = PermissionChange.buildFromParams(inconsistentParams); | |||
thrown.expect(BadRequestException.class); | |||
thrown.expectMessage("Invalid component permission key invalid. Valid values are [admin, codeviewer, issueadmin, scan, user]"); | |||
query.validate(); | |||
} | |||
} |
@@ -19,33 +19,18 @@ | |||
*/ | |||
package org.sonar.server.permission.ws; | |||
import org.junit.Before; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.ExpectedException; | |||
import org.mockito.ArgumentCaptor; | |||
import org.sonar.api.resources.Qualifiers; | |||
import org.sonar.api.utils.System2; | |||
import org.sonar.api.web.UserRole; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbTester; | |||
import org.sonar.db.component.ComponentDto; | |||
import org.sonar.db.component.ComponentTesting; | |||
import org.sonar.db.component.ResourceTypesRule; | |||
import org.sonar.db.user.GroupDto; | |||
import org.sonar.server.component.ComponentFinder; | |||
import org.sonar.server.exceptions.BadRequestException; | |||
import org.sonar.server.exceptions.ForbiddenException; | |||
import org.sonar.server.exceptions.NotFoundException; | |||
import org.sonar.server.exceptions.ServerException; | |||
import org.sonar.server.permission.PermissionChange; | |||
import org.sonar.server.permission.PermissionUpdater; | |||
import org.sonar.server.tester.UserSessionRule; | |||
import org.sonar.server.usergroups.ws.UserGroupFinder; | |||
import org.sonar.server.ws.WsTester; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.verify; | |||
import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN; | |||
import static org.sonar.db.component.ComponentTesting.newProjectDto; | |||
import static org.sonar.db.component.ComponentTesting.newView; | |||
@@ -57,170 +42,139 @@ import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_P | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PROJECT_ID; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PROJECT_KEY; | |||
public class AddGroupActionTest extends BasePermissionWsTest<AddGroupAction> { | |||
public class AddGroupActionTest { | |||
UserSessionRule userSession = UserSessionRule.standalone(); | |||
WsTester ws; | |||
@Rule | |||
public DbTester db = DbTester.create(System2.INSTANCE); | |||
@Rule | |||
public ExpectedException expectedException = ExpectedException.none(); | |||
ResourceTypesRule resourceTypes = new ResourceTypesRule().setRootQualifiers(Qualifiers.PROJECT, Qualifiers.VIEW, "DEV"); | |||
private PermissionUpdater permissionUpdater; | |||
private DbClient dbClient; | |||
private ArgumentCaptor<PermissionChange> permissionChangeCaptor; | |||
@Before | |||
public void setUp() { | |||
permissionUpdater = mock(PermissionUpdater.class); | |||
permissionChangeCaptor = ArgumentCaptor.forClass(PermissionChange.class); | |||
dbClient = db.getDbClient(); | |||
ComponentFinder componentFinder = new ComponentFinder(dbClient); | |||
ws = new WsTester(new PermissionsWs( | |||
new AddGroupAction(dbClient, new PermissionChangeBuilder(new PermissionDependenciesFinder( | |||
dbClient, | |||
componentFinder, | |||
new UserGroupFinder(dbClient), | |||
resourceTypes)), | |||
permissionUpdater))); | |||
userSession.login("admin").setGlobalPermissions(SYSTEM_ADMIN); | |||
private static final String A_PROJECT_UUID = "project-uuid"; | |||
private static final String A_PROJECT_KEY = "project-key"; | |||
@Override | |||
protected AddGroupAction buildWsAction() { | |||
return new AddGroupAction(db.getDbClient(), newPermissionUpdater(), newPermissionWsSupport()); | |||
} | |||
@Test | |||
public void call_permission_service_with_right_data() throws Exception { | |||
insertGroup("sonar-administrators"); | |||
commit(); | |||
public void add_permission_to_group_referenced_by_its_name() throws Exception { | |||
GroupDto group = db.users().insertGroup(defaultOrganizationProvider.getDto(), "sonar-administrators"); | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam(PARAM_GROUP_NAME, "sonar-administrators") | |||
.setParam(PARAM_PERMISSION, SYSTEM_ADMIN) | |||
.execute(); | |||
verify(permissionUpdater).addPermission(permissionChangeCaptor.capture()); | |||
PermissionChange permissionChange = permissionChangeCaptor.getValue(); | |||
assertThat(permissionChange.groupName()).isEqualTo("sonar-administrators"); | |||
assertThat(permissionChange.permission()).isEqualTo(SYSTEM_ADMIN); | |||
assertThat(db.users().selectGroupPermissions(group, null)).containsOnly(SYSTEM_ADMIN); | |||
} | |||
@Test | |||
public void add_with_group_id() throws Exception { | |||
GroupDto group = insertGroup("sonar-administrators"); | |||
commit(); | |||
public void add_permission_to_group_referenced_by_its_id() throws Exception { | |||
GroupDto group = db.users().insertGroup(defaultOrganizationProvider.getDto(), "sonar-administrators"); | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam(PARAM_GROUP_ID, group.getId().toString()) | |||
.setParam(PARAM_PERMISSION, SYSTEM_ADMIN) | |||
.execute(); | |||
verify(permissionUpdater).addPermission(permissionChangeCaptor.capture()); | |||
PermissionChange permissionChange = permissionChangeCaptor.getValue(); | |||
assertThat(permissionChange.groupName()).isEqualTo("sonar-administrators"); | |||
assertThat(db.users().selectGroupPermissions(group, null)).containsOnly(SYSTEM_ADMIN); | |||
} | |||
@Test | |||
public void add_with_project_uuid() throws Exception { | |||
insertGroup("sonar-administrators"); | |||
insertComponent(newProjectDto("project-uuid").setKey("project-key")); | |||
commit(); | |||
public void add_permission_to_project_referenced_by_its_id() throws Exception { | |||
GroupDto group = db.users().insertGroup(defaultOrganizationProvider.getDto(), "sonar-administrators"); | |||
ComponentDto project = db.components().insertComponent(newProjectDto(A_PROJECT_UUID).setKey(A_PROJECT_KEY)); | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam(PARAM_GROUP_NAME, "sonar-administrators") | |||
.setParam(PARAM_PROJECT_ID, "project-uuid") | |||
.setParam(PARAM_GROUP_NAME, group.getName()) | |||
.setParam(PARAM_PROJECT_ID, A_PROJECT_UUID) | |||
.setParam(PARAM_PERMISSION, SYSTEM_ADMIN) | |||
.execute(); | |||
verify(permissionUpdater).addPermission(permissionChangeCaptor.capture()); | |||
PermissionChange permissionChange = permissionChangeCaptor.getValue(); | |||
assertThat(permissionChange.componentKey()).isEqualTo("project-key"); | |||
assertThat(permissionChange.groupName()).isEqualTo("sonar-administrators"); | |||
assertThat(db.users().selectGroupPermissions(group, null)).isEmpty(); | |||
assertThat(db.users().selectGroupPermissions(group, project)).containsOnly(SYSTEM_ADMIN); | |||
} | |||
@Test | |||
public void add_with_project_key() throws Exception { | |||
insertGroup("sonar-administrators"); | |||
insertComponent(newProjectDto("project-uuid").setKey("project-key")); | |||
commit(); | |||
public void add_permission_to_project_referenced_by_its_key() throws Exception { | |||
GroupDto group = db.users().insertGroup(defaultOrganizationProvider.getDto(), "sonar-administrators"); | |||
ComponentDto project = db.components().insertComponent(newProjectDto(A_PROJECT_UUID).setKey(A_PROJECT_KEY)); | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam(PARAM_GROUP_NAME, "sonar-administrators") | |||
.setParam(PARAM_PROJECT_KEY, "project-key") | |||
.setParam(PARAM_GROUP_NAME, group.getName()) | |||
.setParam(PARAM_PROJECT_KEY, A_PROJECT_KEY) | |||
.setParam(PARAM_PERMISSION, SYSTEM_ADMIN) | |||
.execute(); | |||
verify(permissionUpdater).addPermission(permissionChangeCaptor.capture()); | |||
PermissionChange permissionChange = permissionChangeCaptor.getValue(); | |||
assertThat(permissionChange.componentKey()).isEqualTo("project-key"); | |||
assertThat(permissionChange.groupName()).isEqualTo("sonar-administrators"); | |||
assertThat(db.users().selectGroupPermissions(group, null)).isEmpty(); | |||
assertThat(db.users().selectGroupPermissions(group, project)).containsOnly(SYSTEM_ADMIN); | |||
} | |||
@Test | |||
public void add_with_view_uuid() throws Exception { | |||
insertGroup("sonar-administrators"); | |||
insertComponent(newView("view-uuid").setKey("view-key")); | |||
commit(); | |||
GroupDto group = db.users().insertGroup(defaultOrganizationProvider.getDto(), "sonar-administrators"); | |||
ComponentDto view = db.components().insertComponent(newView("view-uuid").setKey("view-key")); | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam(PARAM_GROUP_NAME, "sonar-administrators") | |||
.setParam(PARAM_PROJECT_ID, "view-uuid") | |||
.setParam(PARAM_GROUP_NAME, group.getName()) | |||
.setParam(PARAM_PROJECT_ID, view.uuid()) | |||
.setParam(PARAM_PERMISSION, SYSTEM_ADMIN) | |||
.execute(); | |||
verify(permissionUpdater).addPermission(permissionChangeCaptor.capture()); | |||
PermissionChange permissionChange = permissionChangeCaptor.getValue(); | |||
assertThat(permissionChange.componentKey()).isEqualTo("view-key"); | |||
assertThat(permissionChange.groupName()).isEqualTo("sonar-administrators"); | |||
assertThat(db.users().selectGroupPermissions(group, null)).isEmpty(); | |||
assertThat(db.users().selectGroupPermissions(group, view)).containsOnly(SYSTEM_ADMIN); | |||
} | |||
@Test | |||
public void fail_if_project_uuid_not_found() throws Exception { | |||
expectedException.expect(NotFoundException.class); | |||
insertGroup("sonar-administrators"); | |||
insertComponent(newProjectDto("project-uuid").setKey("project-key")); | |||
commit(); | |||
public void fail_if_project_uuid_is_not_found() throws Exception { | |||
GroupDto group = db.users().insertGroup(defaultOrganizationProvider.getDto(), "sonar-administrators"); | |||
loginAsAdmin(); | |||
expectedException.expect(NotFoundException.class); | |||
newRequest() | |||
.setParam(PARAM_GROUP_NAME, "sonar-administrators") | |||
.setParam(PARAM_PROJECT_ID, "unknown-project-uuid") | |||
.setParam(PARAM_GROUP_NAME, group.getName()) | |||
.setParam(PARAM_PROJECT_ID, "not-found") | |||
.setParam(PARAM_PERMISSION, SYSTEM_ADMIN) | |||
.execute(); | |||
} | |||
@Test | |||
public void fail_if_project_permission_without_project() throws Exception { | |||
expectedException.expect(BadRequestException.class); | |||
public void adding_a_project_permission_fails_if_project_is_not_set() throws Exception { | |||
GroupDto group = db.users().insertGroup(defaultOrganizationProvider.getDto(), "sonar-administrators"); | |||
loginAsAdmin(); | |||
insertGroup("sonar-administrators"); | |||
commit(); | |||
expectedException.expect(BadRequestException.class); | |||
newRequest() | |||
.setParam(PARAM_GROUP_NAME, "sonar-administrators") | |||
.setParam(PARAM_GROUP_NAME, group.getName()) | |||
.setParam(PARAM_PERMISSION, UserRole.ISSUE_ADMIN) | |||
.execute(); | |||
} | |||
@Test | |||
public void fail_if_component_uuid_is_not_a_project() throws Exception { | |||
expectedException.expect(BadRequestException.class); | |||
public void adding_a_project_permission_fails_if_component_is_not_a_project() throws Exception { | |||
GroupDto group = db.users().insertGroup(defaultOrganizationProvider.getDto(), "sonar-administrators"); | |||
ComponentDto project = db.components().insertComponent(newProjectDto(A_PROJECT_UUID).setKey(A_PROJECT_KEY)); | |||
ComponentDto file = db.components().insertComponent(ComponentTesting.newFileDto(project, null, "file-uuid")); | |||
loginAsAdmin(); | |||
insertGroup("sonar-administrators"); | |||
ComponentDto project = newProjectDto("project-uuid").setKey("project-key"); | |||
insertComponent(project); | |||
insertComponent(ComponentTesting.newFileDto(project, null, "file-uuid")); | |||
commit(); | |||
expectedException.expect(BadRequestException.class); | |||
newRequest() | |||
.setParam(PARAM_GROUP_NAME, "sonar-administrators") | |||
.setParam(PARAM_PROJECT_ID, "file-uuid") | |||
.setParam(PARAM_GROUP_NAME, group.getName()) | |||
.setParam(PARAM_PROJECT_ID, file.uuid()) | |||
.setParam(PARAM_PERMISSION, SYSTEM_ADMIN) | |||
.execute(); | |||
} | |||
@Test | |||
public void fail_when_get_request() throws Exception { | |||
loginAsAdmin(); | |||
expectedException.expect(ServerException.class); | |||
ws.newGetRequest(CONTROLLER, ACTION) | |||
wsTester.newGetRequest(CONTROLLER, ACTION) | |||
.setParam(PARAM_GROUP_NAME, "sonar-administrators") | |||
.setParam(PARAM_PERMISSION, SYSTEM_ADMIN) | |||
.execute(); | |||
@@ -228,8 +182,10 @@ public class AddGroupActionTest { | |||
@Test | |||
public void fail_when_group_name_and_group_id_are_missing() throws Exception { | |||
loginAsAdmin(); | |||
expectedException.expect(BadRequestException.class); | |||
expectedException.expectMessage("Group name or group id must be provided, not both"); | |||
expectedException.expectMessage("Group name or group id must be provided"); | |||
newRequest() | |||
.setParam(PARAM_PERMISSION, SYSTEM_ADMIN) | |||
@@ -238,41 +194,52 @@ public class AddGroupActionTest { | |||
@Test | |||
public void fail_when_permission_is_missing() throws Exception { | |||
GroupDto group = db.users().insertGroup(defaultOrganizationProvider.getDto(), "sonar-administrators"); | |||
loginAsAdmin(); | |||
expectedException.expect(IllegalArgumentException.class); | |||
newRequest() | |||
.setParam(PARAM_GROUP_NAME, "sonar-administrators") | |||
.setParam(PARAM_GROUP_NAME, group.getName()) | |||
.execute(); | |||
} | |||
@Test | |||
public void fail_when_project_uuid_and_project_key_are_provided() throws Exception { | |||
db.users().insertGroup(defaultOrganizationProvider.getDto(), "sonar-administrators"); | |||
db.components().insertComponent(newProjectDto(A_PROJECT_UUID).setKey(A_PROJECT_KEY)); | |||
loginAsAdmin(); | |||
expectedException.expect(BadRequestException.class); | |||
expectedException.expectMessage("Project id or project key can be provided, not both."); | |||
insertComponent(newProjectDto("project-uuid").setKey("project-key")); | |||
commit(); | |||
newRequest() | |||
.setParam(PARAM_GROUP_NAME, "sonar-administrators") | |||
.setParam(PARAM_PERMISSION, SYSTEM_ADMIN) | |||
.setParam(PARAM_PROJECT_ID, "project-uuid") | |||
.setParam(PARAM_PROJECT_KEY, "project-key") | |||
.setParam(PARAM_PROJECT_KEY, A_PROJECT_KEY) | |||
.execute(); | |||
} | |||
private WsTester.TestRequest newRequest() { | |||
return ws.newPostRequest(CONTROLLER, ACTION); | |||
} | |||
@Test(expected = ForbiddenException.class) | |||
public void require_admin_permission() throws Exception { | |||
GroupDto group = db.users().insertGroup(defaultOrganizationProvider.getDto(), "sonar-administrators"); | |||
ComponentDto project = db.components().insertComponent(newProjectDto(A_PROJECT_UUID).setKey(A_PROJECT_KEY)); | |||
userSession.login("not-admin"); | |||
private void commit() { | |||
db.getSession().commit(); | |||
newRequest() | |||
.setParam(PARAM_GROUP_NAME, group.getName()) | |||
.setParam(PARAM_PERMISSION, SYSTEM_ADMIN) | |||
.setParam(PARAM_PROJECT_ID, project.uuid()) | |||
.execute(); | |||
} | |||
private void insertComponent(ComponentDto component) { | |||
dbClient.componentDao().insert(db.getSession(), component); | |||
private WsTester.TestRequest newRequest() { | |||
return wsTester.newPostRequest(CONTROLLER, ACTION); | |||
} | |||
private GroupDto insertGroup(String name) { | |||
return dbClient.groupDao().insert(db.getSession(), new GroupDto().setName(name)); | |||
private void loginAsAdmin() { | |||
userSession.login("admin").setGlobalPermissions(SYSTEM_ADMIN); | |||
} | |||
} |
@@ -20,31 +20,15 @@ | |||
package org.sonar.server.permission.ws; | |||
import org.junit.Before; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.ExpectedException; | |||
import org.mockito.ArgumentCaptor; | |||
import org.sonar.api.resources.Qualifiers; | |||
import org.sonar.api.utils.System2; | |||
import org.sonar.api.web.UserRole; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.DbTester; | |||
import org.sonar.db.component.ComponentDto; | |||
import org.sonar.db.component.ResourceTypesRule; | |||
import org.sonar.server.component.ComponentFinder; | |||
import org.sonar.db.user.UserDto; | |||
import org.sonar.server.exceptions.BadRequestException; | |||
import org.sonar.server.exceptions.NotFoundException; | |||
import org.sonar.server.exceptions.ServerException; | |||
import org.sonar.server.permission.PermissionChange; | |||
import org.sonar.server.permission.PermissionUpdater; | |||
import org.sonar.server.tester.UserSessionRule; | |||
import org.sonar.server.usergroups.ws.UserGroupFinder; | |||
import org.sonar.server.ws.WsTester; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.verify; | |||
import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN; | |||
import static org.sonar.db.component.ComponentTesting.newFileDto; | |||
import static org.sonar.db.component.ComponentTesting.newProjectDto; | |||
@@ -56,101 +40,87 @@ import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_P | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PROJECT_KEY; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_USER_LOGIN; | |||
public class AddUserActionTest extends BasePermissionWsTest<AddUserAction> { | |||
public class AddUserActionTest { | |||
@Rule | |||
public DbTester db = DbTester.create(System2.INSTANCE); | |||
@Rule | |||
public ExpectedException expectedException = ExpectedException.none(); | |||
ResourceTypesRule resourceTypes = new ResourceTypesRule() | |||
.setRootQualifiers(Qualifiers.PROJECT, Qualifiers.VIEW, "DEV"); | |||
private static final String A_PROJECT_UUID = "project-uuid"; | |||
private static final String A_PROJECT_KEY = "project-key"; | |||
UserSessionRule userSession = UserSessionRule.standalone(); | |||
WsTester ws; | |||
PermissionUpdater permissionUpdater; | |||
DbClient dbClient; | |||
DbSession dbSession; | |||
ArgumentCaptor<PermissionChange> permissionChangeCaptor = ArgumentCaptor.forClass(PermissionChange.class); | |||
private UserDto user; | |||
@Before | |||
public void setUp() { | |||
permissionUpdater = mock(PermissionUpdater.class); | |||
dbClient = db.getDbClient(); | |||
dbSession = db.getSession(); | |||
ComponentFinder componentFinder = new ComponentFinder(dbClient); | |||
ws = new WsTester(new PermissionsWs( | |||
new AddUserAction(dbClient, permissionUpdater, new PermissionChangeBuilder(new PermissionDependenciesFinder(dbClient, componentFinder, new UserGroupFinder(dbClient), | |||
resourceTypes))))); | |||
userSession.login("admin").setGlobalPermissions(SYSTEM_ADMIN); | |||
user = db.users().insertUser("ray.bradbury"); | |||
} | |||
@Override | |||
protected AddUserAction buildWsAction() { | |||
return new AddUserAction(db.getDbClient(), newPermissionUpdater(), newPermissionWsSupport()); | |||
} | |||
@Test | |||
public void call_permission_service_with_right_data() throws Exception { | |||
ws.newPostRequest(CONTROLLER, ACTION) | |||
.setParam(PARAM_USER_LOGIN, "ray.bradbury") | |||
public void add_permission_to_user() throws Exception { | |||
loginAsAdmin(); | |||
wsTester.newPostRequest(CONTROLLER, ACTION) | |||
.setParam(PARAM_USER_LOGIN, user.getLogin()) | |||
.setParam(PARAM_PERMISSION, SYSTEM_ADMIN) | |||
.execute(); | |||
verify(permissionUpdater).addPermission(permissionChangeCaptor.capture()); | |||
PermissionChange permissionChange = permissionChangeCaptor.getValue(); | |||
assertThat(permissionChange.userLogin()).isEqualTo("ray.bradbury"); | |||
assertThat(permissionChange.permission()).isEqualTo(SYSTEM_ADMIN); | |||
assertThat(db.users().selectUserPermissions(user, null)).containsOnly(SYSTEM_ADMIN); | |||
} | |||
@Test | |||
public void add_user_permission_with_project_uuid() throws Exception { | |||
dbClient.componentDao().insert(dbSession, newProjectDto("project-uuid").setKey("project-key")); | |||
commit(); | |||
public void add_permission_to_project_referenced_by_its_id() throws Exception { | |||
ComponentDto project = db.components().insertComponent(newProjectDto("project-uuid").setKey("project-key")); | |||
ws.newPostRequest(CONTROLLER, ACTION) | |||
.setParam(PARAM_USER_LOGIN, "ray.bradbury") | |||
.setParam(PARAM_PROJECT_ID, "project-uuid") | |||
loginAsAdmin(); | |||
wsTester.newPostRequest(CONTROLLER, ACTION) | |||
.setParam(PARAM_USER_LOGIN, user.getLogin()) | |||
.setParam(PARAM_PROJECT_ID, project.uuid()) | |||
.setParam(PARAM_PERMISSION, SYSTEM_ADMIN) | |||
.execute(); | |||
verify(permissionUpdater).addPermission(permissionChangeCaptor.capture()); | |||
PermissionChange permissionChange = permissionChangeCaptor.getValue(); | |||
assertThat(permissionChange.componentKey()).isEqualTo("project-key"); | |||
assertThat(db.users().selectUserPermissions(user, null)).isEmpty(); | |||
assertThat(db.users().selectUserPermissions(user, project)).containsOnly(SYSTEM_ADMIN); | |||
} | |||
@Test | |||
public void add_user_permissions_with_project_key() throws Exception { | |||
dbClient.componentDao().insert(dbSession, newProjectDto("project-uuid").setKey("project-key")); | |||
commit(); | |||
public void add_permission_to_project_referenced_by_its_key() throws Exception { | |||
ComponentDto project = db.components().insertComponent(newProjectDto("project-uuid").setKey("project-key")); | |||
ws.newPostRequest(CONTROLLER, ACTION) | |||
.setParam(PARAM_USER_LOGIN, "ray.bradbury") | |||
.setParam(PARAM_PROJECT_KEY, "project-key") | |||
loginAsAdmin(); | |||
wsTester.newPostRequest(CONTROLLER, ACTION) | |||
.setParam(PARAM_USER_LOGIN, user.getLogin()) | |||
.setParam(PARAM_PROJECT_KEY, project.getKey()) | |||
.setParam(PARAM_PERMISSION, SYSTEM_ADMIN) | |||
.execute(); | |||
verify(permissionUpdater).addPermission(permissionChangeCaptor.capture()); | |||
PermissionChange permissionChange = permissionChangeCaptor.getValue(); | |||
assertThat(permissionChange.componentKey()).isEqualTo("project-key"); | |||
assertThat(db.users().selectUserPermissions(user, null)).isEmpty(); | |||
assertThat(db.users().selectUserPermissions(user, project)).containsOnly(SYSTEM_ADMIN); | |||
} | |||
@Test | |||
public void add_user_permission_with_view_uuid() throws Exception { | |||
dbClient.componentDao().insert(dbSession, newView("view-uuid").setKey("view-key")); | |||
commit(); | |||
public void add_permission_to_view() throws Exception { | |||
ComponentDto view = db.components().insertComponent(newView("view-uuid").setKey("view-key")); | |||
ws.newPostRequest(CONTROLLER, ACTION) | |||
.setParam(PARAM_USER_LOGIN, "ray.bradbury") | |||
.setParam(PARAM_PROJECT_ID, "view-uuid") | |||
loginAsAdmin(); | |||
wsTester.newPostRequest(CONTROLLER, ACTION) | |||
.setParam(PARAM_USER_LOGIN, user.getLogin()) | |||
.setParam(PARAM_PROJECT_ID, view.uuid()) | |||
.setParam(PARAM_PERMISSION, SYSTEM_ADMIN) | |||
.execute(); | |||
verify(permissionUpdater).addPermission(permissionChangeCaptor.capture()); | |||
PermissionChange permissionChange = permissionChangeCaptor.getValue(); | |||
assertThat(permissionChange.componentKey()).isEqualTo("view-key"); | |||
assertThat(db.users().selectUserPermissions(user, null)).isEmpty(); | |||
assertThat(db.users().selectUserPermissions(user, view)).containsOnly(SYSTEM_ADMIN); | |||
} | |||
@Test | |||
public void fail_when_project_uuid_is_unknown() throws Exception { | |||
loginAsAdmin(); | |||
expectedException.expect(NotFoundException.class); | |||
ws.newPostRequest(CONTROLLER, ACTION) | |||
.setParam(PARAM_USER_LOGIN, "ray.bradbury") | |||
wsTester.newPostRequest(CONTROLLER, ACTION) | |||
.setParam(PARAM_USER_LOGIN, user.getLogin()) | |||
.setParam(PARAM_PROJECT_ID, "unknown-project-uuid") | |||
.setParam(PARAM_PERMISSION, SYSTEM_ADMIN) | |||
.execute(); | |||
@@ -158,22 +128,25 @@ public class AddUserActionTest { | |||
@Test | |||
public void fail_when_project_permission_without_project() throws Exception { | |||
loginAsAdmin(); | |||
expectedException.expect(BadRequestException.class); | |||
ws.newPostRequest(CONTROLLER, ACTION) | |||
.setParam(PARAM_USER_LOGIN, "ray.bradbury") | |||
wsTester.newPostRequest(CONTROLLER, ACTION) | |||
.setParam(PARAM_USER_LOGIN, user.getLogin()) | |||
.setParam(PARAM_PERMISSION, UserRole.ISSUE_ADMIN) | |||
.execute(); | |||
} | |||
@Test | |||
public void fail_when_component_is_not_a_project() throws Exception { | |||
db.components().insertComponent(newFileDto(newProjectDto("project-uuid"), null, "file-uuid")); | |||
loginAsAdmin(); | |||
expectedException.expect(BadRequestException.class); | |||
insertComponent(newFileDto(newProjectDto("project-uuid"), null, "file-uuid")); | |||
commit(); | |||
ws.newPostRequest(CONTROLLER, ACTION) | |||
.setParam(PARAM_USER_LOGIN, "ray.bradbury") | |||
wsTester.newPostRequest(CONTROLLER, ACTION) | |||
.setParam(PARAM_USER_LOGIN, user.getLogin()) | |||
.setParam(PARAM_PROJECT_ID, "file-uuid") | |||
.setParam(PARAM_PERMISSION, SYSTEM_ADMIN) | |||
.execute(); | |||
@@ -181,9 +154,11 @@ public class AddUserActionTest { | |||
@Test | |||
public void fail_when_get_request() throws Exception { | |||
loginAsAdmin(); | |||
expectedException.expect(ServerException.class); | |||
ws.newGetRequest(CONTROLLER, ACTION) | |||
wsTester.newGetRequest(CONTROLLER, ACTION) | |||
.setParam(PARAM_USER_LOGIN, "george.orwell") | |||
.setParam(PARAM_PERMISSION, SYSTEM_ADMIN) | |||
.execute(); | |||
@@ -191,42 +166,43 @@ public class AddUserActionTest { | |||
@Test | |||
public void fail_when_user_login_is_missing() throws Exception { | |||
loginAsAdmin(); | |||
expectedException.expect(IllegalArgumentException.class); | |||
ws.newPostRequest(CONTROLLER, ACTION) | |||
wsTester.newPostRequest(CONTROLLER, ACTION) | |||
.setParam(PARAM_PERMISSION, SYSTEM_ADMIN) | |||
.execute(); | |||
} | |||
@Test | |||
public void fail_when_permission_is_missing() throws Exception { | |||
expectedException.expect(IllegalArgumentException.class); | |||
loginAsAdmin(); | |||
expectedException.expect(NotFoundException.class); | |||
ws.newPostRequest(CONTROLLER, ACTION) | |||
wsTester.newPostRequest(CONTROLLER, ACTION) | |||
.setParam(PARAM_USER_LOGIN, "jrr.tolkien") | |||
.execute(); | |||
} | |||
@Test | |||
public void fail_when_project_uuid_and_project_key_are_provided() throws Exception { | |||
db.components().insertComponent(newProjectDto(A_PROJECT_UUID).setKey(A_PROJECT_KEY)); | |||
loginAsAdmin(); | |||
expectedException.expect(BadRequestException.class); | |||
expectedException.expectMessage("Project id or project key can be provided, not both."); | |||
insertComponent(newProjectDto("project-uuid").setKey("project-key")); | |||
commit(); | |||
ws.newPostRequest(CONTROLLER, ACTION) | |||
wsTester.newPostRequest(CONTROLLER, ACTION) | |||
.setParam(PARAM_PERMISSION, SYSTEM_ADMIN) | |||
.setParam(PARAM_USER_LOGIN, "ray.bradbury") | |||
.setParam(PARAM_USER_LOGIN, user.getLogin()) | |||
.setParam(PARAM_PROJECT_ID, "project-uuid") | |||
.setParam(PARAM_PROJECT_KEY, "project-key") | |||
.execute(); | |||
} | |||
private void insertComponent(ComponentDto component) { | |||
dbClient.componentDao().insert(dbSession, component); | |||
} | |||
private void commit() { | |||
dbSession.commit(); | |||
private void loginAsAdmin() { | |||
userSession.login("admin").setGlobalPermissions(SYSTEM_ADMIN); | |||
} | |||
} |
@@ -0,0 +1,88 @@ | |||
/* | |||
* 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.permission.ws; | |||
import org.junit.Before; | |||
import org.junit.Rule; | |||
import org.junit.rules.ExpectedException; | |||
import org.sonar.api.resources.Qualifiers; | |||
import org.sonar.api.utils.System2; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbTester; | |||
import org.sonar.db.component.ResourceTypesRule; | |||
import org.sonar.db.permission.template.PermissionTemplateDto; | |||
import org.sonar.db.permission.template.PermissionTemplateTesting; | |||
import org.sonar.server.component.ComponentFinder; | |||
import org.sonar.server.issue.index.IssueAuthorizationIndexer; | |||
import org.sonar.server.organization.DefaultOrganizationProviderRule; | |||
import org.sonar.server.permission.GroupPermissionChanger; | |||
import org.sonar.server.permission.PermissionUpdater; | |||
import org.sonar.server.permission.UserPermissionChanger; | |||
import org.sonar.server.tester.UserSessionRule; | |||
import org.sonar.server.usergroups.ws.GroupWsSupport; | |||
import org.sonar.server.ws.WsTester; | |||
import static org.mockito.Mockito.mock; | |||
public abstract class BasePermissionWsTest<A extends PermissionsWsAction> { | |||
@Rule | |||
public DbTester db = DbTester.create(System2.INSTANCE); | |||
@Rule | |||
public ExpectedException expectedException = ExpectedException.none(); | |||
protected DefaultOrganizationProviderRule defaultOrganizationProvider = DefaultOrganizationProviderRule.create(db); | |||
protected UserSessionRule userSession = UserSessionRule.standalone(); | |||
protected WsTester wsTester; | |||
@Before | |||
public void initWsTester() { | |||
wsTester = new WsTester(new PermissionsWs(buildWsAction())); | |||
} | |||
protected abstract A buildWsAction(); | |||
protected GroupWsSupport newGroupWsSupport() { | |||
return new GroupWsSupport(db.getDbClient(), defaultOrganizationProvider); | |||
} | |||
protected PermissionWsSupport newPermissionWsSupport() { | |||
DbClient dbClient = db.getDbClient(); | |||
return new PermissionWsSupport(dbClient, new ComponentFinder(dbClient), newGroupWsSupport(), newRootResourceTypes()); | |||
} | |||
protected ResourceTypesRule newRootResourceTypes() { | |||
return new ResourceTypesRule().setRootQualifiers(Qualifiers.PROJECT, Qualifiers.VIEW, "DEV"); | |||
} | |||
protected PermissionUpdater newPermissionUpdater() { | |||
return new PermissionUpdater(db.getDbClient(), | |||
mock(IssueAuthorizationIndexer.class), | |||
new UserPermissionChanger(db.getDbClient(), userSession), | |||
new GroupPermissionChanger(db.getDbClient(), userSession)); | |||
} | |||
protected PermissionTemplateDto insertTemplate() { | |||
PermissionTemplateDto dto = db.getDbClient().permissionTemplateDao().insert(db.getSession(), PermissionTemplateTesting.newPermissionTemplateDto()); | |||
db.commit(); | |||
return dto; | |||
} | |||
} |
@@ -19,29 +19,16 @@ | |||
*/ | |||
package org.sonar.server.permission.ws; | |||
import com.google.common.io.Resources; | |||
import org.junit.Before; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.ExpectedException; | |||
import org.sonar.api.resources.Qualifiers; | |||
import org.sonar.api.security.DefaultGroups; | |||
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.component.ComponentDbTester; | |||
import org.sonar.db.component.ComponentDto; | |||
import org.sonar.db.component.ResourceTypesRule; | |||
import org.sonar.db.organization.OrganizationDto; | |||
import org.sonar.db.user.GroupDto; | |||
import org.sonar.db.permission.GroupPermissionDto; | |||
import org.sonar.server.component.ComponentFinder; | |||
import org.sonar.server.exceptions.BadRequestException; | |||
import org.sonar.server.exceptions.ForbiddenException; | |||
import org.sonar.server.exceptions.UnauthorizedException; | |||
import org.sonar.server.tester.UserSessionRule; | |||
import org.sonar.server.usergroups.ws.UserGroupFinder; | |||
import org.sonar.server.ws.WsActionTester; | |||
import org.sonar.server.ws.WsTester; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.sonar.api.server.ws.WebService.Param.PAGE; | |||
@@ -53,75 +40,95 @@ import static org.sonar.core.permission.GlobalPermissions.SCAN_EXECUTION; | |||
import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN; | |||
import static org.sonar.db.component.ComponentTesting.newProjectDto; | |||
import static org.sonar.db.component.ComponentTesting.newView; | |||
import static org.sonar.test.JsonAssert.assertJson; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.CONTROLLER; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PERMISSION; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PROJECT_ID; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PROJECT_KEY; | |||
public class GroupsActionTest { | |||
public class GroupsActionTest extends BasePermissionWsTest<GroupsAction> { | |||
@Rule | |||
public ExpectedException expectedException = ExpectedException.none(); | |||
@Rule | |||
public UserSessionRule userSession = UserSessionRule.standalone(); | |||
@Rule | |||
public DbTester db = DbTester.create(System2.INSTANCE); | |||
private GroupDto group1; | |||
private GroupDto group2; | |||
private GroupDto group3; | |||
ComponentDbTester componentDb = new ComponentDbTester(db); | |||
ResourceTypesRule resourceTypes = new ResourceTypesRule().setRootQualifiers(Qualifiers.PROJECT, Qualifiers.VIEW, "DEV"); | |||
DbClient dbClient; | |||
DbSession dbSession; | |||
WsActionTester ws; | |||
GroupsAction underTest; | |||
@Override | |||
protected GroupsAction buildWsAction() { | |||
return new GroupsAction( | |||
db.getDbClient(), | |||
userSession, | |||
newPermissionWsSupport()); | |||
} | |||
@Before | |||
public void setUp() { | |||
dbClient = db.getDbClient(); | |||
dbSession = db.getSession(); | |||
underTest = new GroupsAction( | |||
dbClient, | |||
userSession, | |||
new PermissionDependenciesFinder(dbClient, new ComponentFinder(dbClient), new UserGroupFinder(dbClient), resourceTypes)); | |||
ws = new WsActionTester(underTest); | |||
userSession.login("login").setGlobalPermissions(SYSTEM_ADMIN); | |||
GroupDto group1 = insertGroup(new GroupDto().setName("group-1-name").setDescription("group-1-description")); | |||
GroupDto group2 = insertGroup(new GroupDto().setName("group-2-name").setDescription("group-2-description")); | |||
GroupDto group3 = insertGroup(new GroupDto().setName("group-3-name").setDescription("group-3-description")); | |||
insertGroupRole(new GroupPermissionDto().setGroupId(group1.getId()).setRole(SCAN_EXECUTION)); | |||
insertGroupRole(new GroupPermissionDto().setGroupId(group2.getId()).setRole(SCAN_EXECUTION)); | |||
insertGroupRole(new GroupPermissionDto().setGroupId(null).setRole(SCAN_EXECUTION)); | |||
insertGroupRole(new GroupPermissionDto().setGroupId(group3.getId()).setRole(SYSTEM_ADMIN)); | |||
OrganizationDto defOrg = defaultOrganizationProvider.getDto(); | |||
group1 = db.users().insertGroup(defOrg, "group-1-name"); | |||
group2 = db.users().insertGroup(defOrg, "group-2-name"); | |||
group3 = db.users().insertGroup(defOrg, "group-3-name"); | |||
db.users().insertPermissionOnGroup(group1, SCAN_EXECUTION); | |||
db.users().insertPermissionOnGroup(group2, SCAN_EXECUTION); | |||
db.users().insertPermissionOnGroup(group3, SYSTEM_ADMIN); | |||
db.users().insertPermissionOnAnyone(defOrg, SCAN_EXECUTION); | |||
db.commit(); | |||
} | |||
@Test | |||
public void search_for_groups_with_one_permission() { | |||
String result = ws.newRequest() | |||
public void search_for_groups_with_one_permission() throws Exception { | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam(PARAM_PERMISSION, SCAN_EXECUTION) | |||
.execute().getInput(); | |||
assertJson(result).isSimilarTo(Resources.getResource(getClass(), "GroupsActionTest/groups.json")); | |||
.execute() | |||
.assertJson("{\n" + | |||
" \"paging\": {\n" + | |||
" \"pageIndex\": 1,\n" + | |||
" \"pageSize\": 20,\n" + | |||
" \"total\": 3\n" + | |||
" },\n" + | |||
" \"groups\": [\n" + | |||
" {\n" + | |||
" \"name\": \"Anyone\",\n" + | |||
" \"permissions\": [\n" + | |||
" \"scan\"\n" + | |||
" ]\n" + | |||
" },\n" + | |||
" {\n" + | |||
" \"name\": \"group-1-name\",\n" + | |||
" \"description\": \"" + group1.getDescription() + "\",\n" + | |||
" \"permissions\": [\n" + | |||
" \"scan\"\n" + | |||
" ]\n" + | |||
" },\n" + | |||
" {\n" + | |||
" \"name\": \"group-2-name\",\n" + | |||
" \"description\": \"" + group2.getDescription() + "\",\n" + | |||
" \"permissions\": [\n" + | |||
" \"scan\"\n" + | |||
" ]\n" + | |||
" }\n" + | |||
" ]\n" + | |||
"}\n"); | |||
} | |||
@Test | |||
public void search_with_selection() { | |||
String result = ws.newRequest() | |||
public void search_with_selection() throws Exception { | |||
loginAsAdmin(); | |||
String result = newRequest() | |||
.setParam(PARAM_PERMISSION, SCAN_EXECUTION) | |||
.execute().getInput(); | |||
.execute() | |||
.outputAsString(); | |||
assertThat(result).containsSequence(DefaultGroups.ANYONE, "group-1", "group-2"); | |||
} | |||
@Test | |||
public void search_groups_with_pagination() { | |||
String result = ws.newRequest() | |||
public void search_groups_with_pagination() throws Exception { | |||
loginAsAdmin(); | |||
String result = newRequest() | |||
.setParam(PARAM_PERMISSION, SCAN_EXECUTION) | |||
.setParam(PAGE_SIZE, "1") | |||
.setParam(PAGE, "3") | |||
.execute().getInput(); | |||
.execute() | |||
.outputAsString(); | |||
assertThat(result).contains("group-2") | |||
.doesNotContain("group-1") | |||
@@ -129,11 +136,13 @@ public class GroupsActionTest { | |||
} | |||
@Test | |||
public void search_groups_with_query() { | |||
String result = ws.newRequest() | |||
public void search_groups_with_query() throws Exception { | |||
loginAsAdmin(); | |||
String result = newRequest() | |||
.setParam(PARAM_PERMISSION, SCAN_EXECUTION) | |||
.setParam(TEXT_QUERY, "group-") | |||
.execute().getInput(); | |||
.execute() | |||
.outputAsString(); | |||
assertThat(result) | |||
.contains("group-1", "group-2") | |||
@@ -141,29 +150,23 @@ public class GroupsActionTest { | |||
} | |||
@Test | |||
public void search_groups_with_project_permissions() { | |||
userSession.login().addProjectUuidPermissions(ADMIN, "project-uuid"); | |||
ComponentDto project = componentDb.insertComponent(newProjectDto("project-uuid")); | |||
GroupDto group = insertGroup(new GroupDto().setName("project-group-name")); | |||
insertGroupRole(new GroupPermissionDto() | |||
.setGroupId(group.getId()) | |||
.setRole(ISSUE_ADMIN) | |||
.setResourceId(project.getId())); | |||
public void search_groups_with_project_permissions() throws Exception { | |||
ComponentDto project = db.components().insertComponent(newProjectDto("project-uuid")); | |||
GroupDto group = db.users().insertGroup(defaultOrganizationProvider.getDto(), "project-group-name"); | |||
db.users().insertProjectPermissionOnGroup(group, ISSUE_ADMIN, project); | |||
ComponentDto anotherProject = componentDb.insertComponent(newProjectDto()); | |||
GroupDto anotherGroup = insertGroup(new GroupDto().setName("another-project-group-name")); | |||
insertGroupRole(new GroupPermissionDto() | |||
.setGroupId(anotherGroup.getId()) | |||
.setRole(ISSUE_ADMIN) | |||
.setResourceId(anotherProject.getId())); | |||
ComponentDto anotherProject = db.components().insertComponent(newProjectDto()); | |||
GroupDto anotherGroup = db.users().insertGroup(defaultOrganizationProvider.getDto(), "another-project-group-name"); | |||
db.users().insertProjectPermissionOnGroup(anotherGroup, ISSUE_ADMIN, anotherProject); | |||
GroupDto groupWithoutPermission = insertGroup(new GroupDto().setName("group-without-permission")); | |||
GroupDto groupWithoutPermission = db.users().insertGroup(defaultOrganizationProvider.getDto(), "group-without-permission"); | |||
String result = ws.newRequest() | |||
userSession.login().addProjectUuidPermissions(ADMIN, "project-uuid"); | |||
String result = newRequest() | |||
.setParam(PARAM_PERMISSION, ISSUE_ADMIN) | |||
.setParam(PARAM_PROJECT_ID, "project-uuid") | |||
.execute().getInput(); | |||
.execute() | |||
.outputAsString(); | |||
assertThat(result).contains(group.getName()) | |||
.doesNotContain(anotherGroup.getName()) | |||
@@ -171,24 +174,21 @@ public class GroupsActionTest { | |||
} | |||
@Test | |||
public void return_also_groups_without_permission_when_search_query() { | |||
userSession.login().setGlobalPermissions(SYSTEM_ADMIN); | |||
public void return_also_groups_without_permission_when_search_query() throws Exception { | |||
ComponentDto project = db.components().insertComponent(newProjectDto("project-uuid")); | |||
GroupDto group = db.users().insertGroup(defaultOrganizationProvider.getDto(), "group-with-permission"); | |||
db.users().insertProjectPermissionOnGroup(group, ISSUE_ADMIN, project); | |||
ComponentDto project = componentDb.insertComponent(newProjectDto("project-uuid")); | |||
GroupDto group = insertGroup(new GroupDto().setName("group-with-permission")); | |||
insertGroupRole(new GroupPermissionDto() | |||
.setGroupId(group.getId()) | |||
.setRole(ISSUE_ADMIN) | |||
.setResourceId(project.getId())); | |||
GroupDto groupWithoutPermission = db.users().insertGroup(defaultOrganizationProvider.getDto(), "group-without-permission"); | |||
GroupDto anotherGroup = db.users().insertGroup(defaultOrganizationProvider.getDto(), "another-group"); | |||
GroupDto groupWithoutPermission = insertGroup(new GroupDto().setName("group-without-permission")); | |||
GroupDto anotherGroup = insertGroup(new GroupDto().setName("another-group")); | |||
String result = ws.newRequest() | |||
loginAsAdmin(); | |||
String result = newRequest() | |||
.setParam(PARAM_PERMISSION, ISSUE_ADMIN) | |||
.setParam(PARAM_PROJECT_ID, "project-uuid") | |||
.setParam(TEXT_QUERY, "group-with") | |||
.execute().getInput(); | |||
.execute() | |||
.outputAsString(); | |||
assertThat(result).contains(group.getName()) | |||
.doesNotContain(groupWithoutPermission.getName()) | |||
@@ -196,59 +196,52 @@ public class GroupsActionTest { | |||
} | |||
@Test | |||
public void return_only_groups_with_permission_when_no_search_query() { | |||
userSession.login().setGlobalPermissions(SYSTEM_ADMIN); | |||
ComponentDto project = componentDb.insertComponent(newProjectDto("project-uuid")); | |||
GroupDto group = insertGroup(new GroupDto().setName("project-group-name")); | |||
insertGroupRole(new GroupPermissionDto() | |||
.setGroupId(group.getId()) | |||
.setRole(ISSUE_ADMIN) | |||
.setResourceId(project.getId())); | |||
public void return_only_groups_with_permission_when_no_search_query() throws Exception { | |||
ComponentDto project = db.components().insertComponent(newProjectDto("project-uuid")); | |||
GroupDto group = db.users().insertGroup(defaultOrganizationProvider.getDto(), "project-group-name"); | |||
db.users().insertProjectPermissionOnGroup(group, ISSUE_ADMIN, project); | |||
GroupDto groupWithoutPermission = insertGroup(new GroupDto().setName("group-without-permission")); | |||
GroupDto groupWithoutPermission = db.users().insertGroup(defaultOrganizationProvider.getDto(), "group-without-permission"); | |||
String result = ws.newRequest() | |||
loginAsAdmin(); | |||
String result = newRequest() | |||
.setParam(PARAM_PERMISSION, ISSUE_ADMIN) | |||
.setParam(PARAM_PROJECT_ID, "project-uuid") | |||
.execute().getInput(); | |||
.setParam(PARAM_PROJECT_ID, project.uuid()) | |||
.execute() | |||
.outputAsString(); | |||
assertThat(result).contains("project-group-name") | |||
assertThat(result).contains(group.getName()) | |||
.doesNotContain(groupWithoutPermission.getName()); | |||
} | |||
@Test | |||
public void return_anyone_group_when_search_query_and_no_param_permission() { | |||
userSession.login().setGlobalPermissions(SYSTEM_ADMIN); | |||
ComponentDto project = componentDb.insertComponent(newProjectDto("project-uuid")); | |||
GroupDto group = insertGroup(new GroupDto().setName("group-with-permission")); | |||
insertGroupRole(new GroupPermissionDto() | |||
.setGroupId(group.getId()) | |||
.setRole(ISSUE_ADMIN) | |||
.setResourceId(project.getId())); | |||
String result = ws.newRequest() | |||
.setParam(PARAM_PROJECT_ID, "project-uuid") | |||
public void return_anyone_group_when_search_query_and_no_param_permission() throws Exception { | |||
ComponentDto project = db.components().insertComponent(newProjectDto("project-uuid")); | |||
GroupDto group = db.users().insertGroup(defaultOrganizationProvider.getDto(), "group-with-permission"); | |||
db.users().insertProjectPermissionOnGroup(group, ISSUE_ADMIN, project); | |||
loginAsAdmin(); | |||
String result = newRequest() | |||
.setParam(PARAM_PROJECT_ID, project.uuid()) | |||
.setParam(TEXT_QUERY, "nyo") | |||
.execute().getInput(); | |||
.execute() | |||
.outputAsString(); | |||
assertThat(result).contains("Anyone"); | |||
} | |||
@Test | |||
public void search_groups_on_views() { | |||
ComponentDto view = componentDb.insertComponent(newView("view-uuid").setKey("view-key")); | |||
GroupDto group = insertGroup(new GroupDto().setName("project-group-name")); | |||
insertGroupRole(new GroupPermissionDto() | |||
.setGroupId(group.getId()) | |||
.setRole(ISSUE_ADMIN) | |||
.setResourceId(view.getId())); | |||
String result = ws.newRequest() | |||
public void search_groups_on_views() throws Exception { | |||
ComponentDto view = db.components().insertComponent(newView("view-uuid").setKey("view-key")); | |||
GroupDto group = db.users().insertGroup(defaultOrganizationProvider.getDto(), "project-group-name"); | |||
db.users().insertProjectPermissionOnGroup(group, ISSUE_ADMIN, view); | |||
loginAsAdmin(); | |||
String result = newRequest() | |||
.setParam(PARAM_PERMISSION, ISSUE_ADMIN) | |||
.setParam(PARAM_PROJECT_ID, "view-uuid") | |||
.execute().getInput(); | |||
.execute() | |||
.outputAsString(); | |||
assertThat(result).contains("project-group-name") | |||
.doesNotContain("group-1") | |||
@@ -257,59 +250,44 @@ public class GroupsActionTest { | |||
} | |||
@Test | |||
public void fail_if_project_permission_without_project() { | |||
expectedException.expect(BadRequestException.class); | |||
ws.newRequest() | |||
.setParam(PARAM_PERMISSION, ISSUE_ADMIN) | |||
.execute(); | |||
} | |||
@Test | |||
public void fail_if_not_logged_in() { | |||
public void fail_if_not_logged_in() throws Exception { | |||
expectedException.expect(UnauthorizedException.class); | |||
userSession.anonymous(); | |||
ws.newRequest() | |||
newRequest() | |||
.setParam(PARAM_PERMISSION, "scan") | |||
.execute(); | |||
} | |||
@Test | |||
public void fail_if_insufficient_privileges() { | |||
public void fail_if_insufficient_privileges() throws Exception { | |||
expectedException.expect(ForbiddenException.class); | |||
userSession.login("login"); | |||
ws.newRequest() | |||
userSession.login("login"); | |||
newRequest() | |||
.setParam(PARAM_PERMISSION, "scan") | |||
.execute(); | |||
} | |||
@Test | |||
public void fail_if_project_uuid_and_project_key_are_provided() { | |||
public void fail_if_project_uuid_and_project_key_are_provided() throws Exception { | |||
db.components().insertComponent(newProjectDto("project-uuid").setKey("project-key")); | |||
expectedException.expect(BadRequestException.class); | |||
dbClient.componentDao().insert(dbSession, newProjectDto("project-uuid").setKey("project-key")); | |||
ws.newRequest() | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam(PARAM_PERMISSION, SCAN_EXECUTION) | |||
.setParam(PARAM_PROJECT_ID, "project-uuid") | |||
.setParam(PARAM_PROJECT_KEY, "project-key") | |||
.execute(); | |||
} | |||
private GroupDto insertGroup(GroupDto group) { | |||
GroupDto result = dbClient.groupDao().insert(dbSession, group); | |||
commit(); | |||
return result; | |||
} | |||
private void insertGroupRole(GroupPermissionDto groupRole) { | |||
dbClient.roleDao().insertGroupRole(dbSession, groupRole); | |||
commit(); | |||
private WsTester.TestRequest newRequest() { | |||
return wsTester.newPostRequest(CONTROLLER, "groups"); | |||
} | |||
private void commit() { | |||
dbSession.commit(); | |||
private void loginAsAdmin() { | |||
userSession.login("login").setGlobalPermissions(SYSTEM_ADMIN); | |||
} | |||
} |
@@ -29,6 +29,6 @@ public class PermissionsWsModuleTest { | |||
public void verify_count_of_added_components() { | |||
ComponentContainer container = new ComponentContainer(); | |||
new PermissionsWsModule().configure(container); | |||
assertThat(container.size()).isEqualTo(2 + 29); | |||
assertThat(container.size()).isEqualTo(2 + 33); | |||
} | |||
} |
@@ -23,6 +23,8 @@ import org.junit.Before; | |||
import org.junit.Test; | |||
import org.sonar.api.server.ws.WebService; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.server.permission.ws.template.TemplateGroupsAction; | |||
import org.sonar.server.permission.ws.template.TemplateUsersAction; | |||
import org.sonar.server.user.UserSession; | |||
import org.sonar.server.ws.WsTester; | |||
@@ -38,12 +40,11 @@ public class PermissionsWsTest { | |||
public void setUp() { | |||
DbClient dbClient = mock(DbClient.class); | |||
UserSession userSession = mock(UserSession.class); | |||
PermissionDependenciesFinder permissionDependenciesFinder = mock(PermissionDependenciesFinder.class); | |||
PermissionWsSupport permissionWsSupport = mock(PermissionWsSupport.class); | |||
ws = new WsTester(new PermissionsWs( | |||
new TemplateUsersAction(dbClient, userSession, permissionDependenciesFinder), | |||
new TemplateGroupsAction(dbClient, userSession, permissionDependenciesFinder) | |||
)); | |||
new TemplateUsersAction(dbClient, userSession, permissionWsSupport), | |||
new TemplateGroupsAction(dbClient, userSession, permissionWsSupport))); | |||
} | |||
@Test |
@@ -20,32 +20,18 @@ | |||
package org.sonar.server.permission.ws; | |||
import org.junit.Before; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.ExpectedException; | |||
import org.mockito.ArgumentCaptor; | |||
import org.sonar.api.resources.Qualifiers; | |||
import org.sonar.api.utils.System2; | |||
import org.sonar.api.web.UserRole; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.DbTester; | |||
import org.sonar.db.component.ComponentDto; | |||
import org.sonar.db.component.ResourceTypesRule; | |||
import org.sonar.db.user.GroupDto; | |||
import org.sonar.server.component.ComponentFinder; | |||
import org.sonar.server.exceptions.BadRequestException; | |||
import org.sonar.server.exceptions.NotFoundException; | |||
import org.sonar.server.exceptions.ServerException; | |||
import org.sonar.server.permission.PermissionChange; | |||
import org.sonar.server.permission.PermissionUpdater; | |||
import org.sonar.server.tester.UserSessionRule; | |||
import org.sonar.server.usergroups.ws.UserGroupFinder; | |||
import org.sonar.server.ws.WsTester; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.verify; | |||
import static org.sonar.api.web.UserRole.ADMIN; | |||
import static org.sonar.api.web.UserRole.ISSUE_ADMIN; | |||
import static org.sonar.core.permission.GlobalPermissions.PROVISIONING; | |||
import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN; | |||
import static org.sonar.db.component.ComponentTesting.newFileDto; | |||
import static org.sonar.db.component.ComponentTesting.newProjectDto; | |||
@@ -58,117 +44,127 @@ import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_P | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PROJECT_ID; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PROJECT_KEY; | |||
public class RemoveGroupActionTest extends BasePermissionWsTest<RemoveGroupAction> { | |||
public class RemoveGroupActionTest { | |||
UserSessionRule userSession = UserSessionRule.standalone(); | |||
WsTester ws; | |||
@Rule | |||
public DbTester db = DbTester.create(System2.INSTANCE); | |||
@Rule | |||
public ExpectedException expectedException = ExpectedException.none(); | |||
ResourceTypesRule resourceTypes = new ResourceTypesRule().setRootQualifiers(Qualifiers.PROJECT, Qualifiers.VIEW, "DEV"); | |||
private PermissionUpdater permissionUpdater; | |||
private ArgumentCaptor<PermissionChange> permissionChangeCaptor = ArgumentCaptor.forClass(PermissionChange.class); | |||
final DbSession dbSession = db.getSession(); | |||
private static final String A_PROJECT_UUID = "project-uuid"; | |||
private static final String A_PROJECT_KEY = "project-key"; | |||
private GroupDto aGroup; | |||
@Before | |||
public void setUp() { | |||
permissionUpdater = mock(PermissionUpdater.class); | |||
DbClient dbClient = db.getDbClient(); | |||
ComponentFinder componentFinder = new ComponentFinder(dbClient); | |||
ws = new WsTester(new PermissionsWs( | |||
new RemoveGroupAction(dbClient, new PermissionChangeBuilder(new PermissionDependenciesFinder(dbClient, componentFinder, new UserGroupFinder(dbClient), resourceTypes)), permissionUpdater))); | |||
userSession.login("admin").setGlobalPermissions(SYSTEM_ADMIN); | |||
aGroup = db.users().insertGroup(defaultOrganizationProvider.getDto(), "sonar-administrators"); | |||
} | |||
@Override | |||
protected RemoveGroupAction buildWsAction() { | |||
return new RemoveGroupAction(db.getDbClient(), newPermissionUpdater(), newPermissionWsSupport()); | |||
} | |||
@Test | |||
public void call_permission_service_with_right_data() throws Exception { | |||
insertGroup("sonar-administrators"); | |||
commit(); | |||
public void remove_permission_using_group_name() throws Exception { | |||
db.users().insertPermissionOnGroup(aGroup, SYSTEM_ADMIN); | |||
db.users().insertPermissionOnGroup(aGroup, PROVISIONING); | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam(PARAM_GROUP_NAME, "sonar-administrators") | |||
.setParam(PARAM_PERMISSION, SYSTEM_ADMIN) | |||
.setParam(PARAM_GROUP_NAME, aGroup.getName()) | |||
.setParam(PARAM_PERMISSION, PROVISIONING) | |||
.execute(); | |||
verify(permissionUpdater).removePermission(permissionChangeCaptor.capture()); | |||
PermissionChange permissionChange = permissionChangeCaptor.getValue(); | |||
assertThat(permissionChange.groupName()).isEqualTo("sonar-administrators"); | |||
assertThat(permissionChange.permission()).isEqualTo(SYSTEM_ADMIN); | |||
assertThat(db.users().selectGroupPermissions(aGroup, null)).containsOnly(SYSTEM_ADMIN); | |||
} | |||
@Test | |||
public void remove_by_group_id() throws Exception { | |||
GroupDto group = insertGroup("sonar-administrators"); | |||
commit(); | |||
public void remove_permission_using_group_id() throws Exception { | |||
db.users().insertPermissionOnGroup(aGroup, SYSTEM_ADMIN); | |||
db.users().insertPermissionOnGroup(aGroup, PROVISIONING); | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam(PARAM_GROUP_ID, group.getId().toString()) | |||
.setParam(PARAM_PERMISSION, SYSTEM_ADMIN) | |||
.setParam(PARAM_GROUP_ID, aGroup.getId().toString()) | |||
.setParam(PARAM_PERMISSION, PROVISIONING) | |||
.execute(); | |||
verify(permissionUpdater).removePermission(permissionChangeCaptor.capture()); | |||
PermissionChange permissionChange = permissionChangeCaptor.getValue(); | |||
assertThat(permissionChange.groupName()).isEqualTo("sonar-administrators"); | |||
assertThat(db.users().selectGroupPermissions(aGroup, null)).containsOnly(SYSTEM_ADMIN); | |||
} | |||
@Test | |||
public void remove_with_project_uuid() throws Exception { | |||
insertComponent(newProjectDto("project-uuid").setKey("project-key")); | |||
insertGroup("sonar-administrators"); | |||
commit(); | |||
public void remove_project_permission() throws Exception { | |||
ComponentDto project = db.components().insertComponent(newProjectDto(A_PROJECT_UUID).setKey(A_PROJECT_KEY)); | |||
db.users().insertPermissionOnGroup(aGroup, SYSTEM_ADMIN); | |||
db.users().insertProjectPermissionOnGroup(aGroup, ADMIN, project); | |||
db.users().insertProjectPermissionOnGroup(aGroup, ISSUE_ADMIN, project); | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam(PARAM_GROUP_NAME, "sonar-administrators") | |||
.setParam(PARAM_PROJECT_ID, "project-uuid") | |||
.setParam(PARAM_PERMISSION, SYSTEM_ADMIN) | |||
.setParam(PARAM_GROUP_NAME, aGroup.getName()) | |||
.setParam(PARAM_PROJECT_ID, project.uuid()) | |||
.setParam(PARAM_PERMISSION, ADMIN) | |||
.execute(); | |||
verify(permissionUpdater).removePermission(permissionChangeCaptor.capture()); | |||
PermissionChange permissionChange = permissionChangeCaptor.getValue(); | |||
assertThat(permissionChange.componentKey()).isEqualTo("project-key"); | |||
assertThat(db.users().selectGroupPermissions(aGroup, null)).containsOnly(SYSTEM_ADMIN); | |||
assertThat(db.users().selectGroupPermissions(aGroup, project)).containsOnly(ISSUE_ADMIN); | |||
} | |||
@Test | |||
public void remove_with_view_uuid() throws Exception { | |||
insertComponent(newView("view-uuid").setKey("view-key")); | |||
insertGroup("sonar-administrators"); | |||
db.commit(); | |||
ComponentDto view = db.components().insertComponent(newView("view-uuid").setKey("view-key")); | |||
db.users().insertPermissionOnGroup(aGroup, SYSTEM_ADMIN); | |||
db.users().insertProjectPermissionOnGroup(aGroup, ADMIN, view); | |||
db.users().insertProjectPermissionOnGroup(aGroup, ISSUE_ADMIN, view); | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam(PARAM_GROUP_NAME, "sonar-administrators") | |||
.setParam(PARAM_PROJECT_ID, "view-uuid") | |||
.setParam(PARAM_PERMISSION, SYSTEM_ADMIN) | |||
.setParam(PARAM_GROUP_NAME, aGroup.getName()) | |||
.setParam(PARAM_PROJECT_ID, view.uuid()) | |||
.setParam(PARAM_PERMISSION, ADMIN) | |||
.execute(); | |||
verify(permissionUpdater).removePermission(permissionChangeCaptor.capture()); | |||
PermissionChange permissionChange = permissionChangeCaptor.getValue(); | |||
assertThat(permissionChange.componentKey()).isEqualTo("view-key"); | |||
assertThat(db.users().selectGroupPermissions(aGroup, null)).containsOnly(SYSTEM_ADMIN); | |||
assertThat(db.users().selectGroupPermissions(aGroup, view)).containsOnly(ISSUE_ADMIN); | |||
} | |||
@Test | |||
public void remove_with_project_key() throws Exception { | |||
insertComponent(newProjectDto("project-uuid").setKey("project-key")); | |||
insertGroup("sonar-administrators"); | |||
db.commit(); | |||
ComponentDto project = db.components().insertComponent(newProjectDto(A_PROJECT_UUID).setKey(A_PROJECT_KEY)); | |||
db.users().insertPermissionOnGroup(aGroup, SYSTEM_ADMIN); | |||
db.users().insertProjectPermissionOnGroup(aGroup, ADMIN, project); | |||
db.users().insertProjectPermissionOnGroup(aGroup, ISSUE_ADMIN, project); | |||
loginAsAdmin(); | |||
newRequest() | |||
.setParam(PARAM_GROUP_NAME, "sonar-administrators") | |||
.setParam(PARAM_PROJECT_KEY, "project-key") | |||
.setParam(PARAM_PERMISSION, SYSTEM_ADMIN) | |||
.setParam(PARAM_GROUP_NAME, aGroup.getName()) | |||
.setParam(PARAM_PROJECT_KEY, project.getKey()) | |||
.setParam(PARAM_PERMISSION, ADMIN) | |||
.execute(); | |||
verify(permissionUpdater).removePermission(permissionChangeCaptor.capture()); | |||
PermissionChange permissionChange = permissionChangeCaptor.getValue(); | |||
assertThat(permissionChange.componentKey()).isEqualTo("project-key"); | |||
assertThat(db.users().selectGroupPermissions(aGroup, null)).containsOnly(SYSTEM_ADMIN); | |||
assertThat(db.users().selectGroupPermissions(aGroup, project)).containsOnly(ISSUE_ADMIN); | |||
} | |||
@Test | |||
public void fail_to_remove_last_sysadmin_permission() throws Exception { | |||
db.users().insertPermissionOnGroup(aGroup, SYSTEM_ADMIN); | |||
db.users().insertPermissionOnGroup(aGroup, PROVISIONING); | |||
loginAsAdmin(); | |||
expectedException.expect(BadRequestException.class); | |||
expectedException.expectMessage("Last group with 'admin' permission. Permission cannot be removed."); | |||
newRequest() | |||
.setParam(PARAM_GROUP_NAME, aGroup.getName()) | |||
.setParam(PARAM_PERMISSION, SYSTEM_ADMIN) | |||
.execute(); | |||
} | |||
@Test | |||
public void fail_when_project_does_not_exist() throws Exception { | |||
expectedException.expect(NotFoundException.class); | |||
expectedException.expectMessage("Project id 'unknown-project-uuid' not found"); | |||
newRequest() | |||
.setParam(PARAM_GROUP_NAME, "sonar-administrators") | |||
.setParam(PARAM_GROUP_NAME, aGroup.getName()) | |||
.setParam(PARAM_PROJECT_ID, "unknown-project-uuid") | |||
.setParam(PARAM_PERMISSION, SYSTEM_ADMIN) | |||
.execute(); | |||
@@ -177,23 +173,24 @@ public class RemoveGroupActionTest { | |||
@Test | |||
public void fail_when_project_project_permission_without_project() throws Exception { | |||
expectedException.expect(BadRequestException.class); | |||
expectedException.expectMessage("Invalid global permission 'issueadmin'. Valid values are [admin, profileadmin, gateadmin, scan, provisioning]"); | |||
newRequest() | |||
.setParam(PARAM_GROUP_NAME, "sonar-administrators") | |||
.setParam(PARAM_PERMISSION, UserRole.ISSUE_ADMIN) | |||
.setParam(PARAM_GROUP_NAME, aGroup.getName()) | |||
.setParam(PARAM_PERMISSION, ISSUE_ADMIN) | |||
.execute(); | |||
} | |||
@Test | |||
public void fail_when_component_is_not_a_project() throws Exception { | |||
ComponentDto file = db.components().insertComponent(newFileDto(newProjectDto(A_PROJECT_UUID), null, "file-uuid")); | |||
expectedException.expect(BadRequestException.class); | |||
insertComponent(newFileDto(newProjectDto("project-uuid"), null, "file-uuid")); | |||
insertGroup("sonar-administrators"); | |||
commit(); | |||
expectedException.expectMessage("Component 'KEY_file-uuid' (id: file-uuid) must be a project or a module."); | |||
newRequest() | |||
.setParam(PARAM_GROUP_NAME, "sonar-administrators") | |||
.setParam(PARAM_PROJECT_ID, "file-uuid") | |||
.setParam(PARAM_GROUP_NAME, aGroup.getName()) | |||
.setParam(PARAM_PROJECT_ID, file.uuid()) | |||
.setParam(PARAM_PERMISSION, SYSTEM_ADMIN) | |||
.execute(); | |||
} | |||
@@ -201,9 +198,10 @@ public class RemoveGroupActionTest { | |||
@Test | |||
public void fail_when_get_request() throws Exception { | |||
expectedException.expect(ServerException.class); | |||
expectedException.expectMessage("HTTP method POST is required"); | |||
ws.newGetRequest(CONTROLLER, ACTION) | |||
.setParam(PARAM_GROUP_NAME, "sonar-administrators") | |||
wsTester.newGetRequest(CONTROLLER, ACTION) | |||
.setParam(PARAM_GROUP_NAME, aGroup.getName()) | |||
.setParam(PARAM_PERMISSION, SYSTEM_ADMIN) | |||
.execute(); | |||
} | |||
@@ -211,6 +209,7 @@ public class RemoveGroupActionTest { | |||
@Test | |||
public void fail_when_group_name_is_missing() throws Exception { | |||
expectedException.expect(BadRequestException.class); | |||
expectedException.expectMessage("Group name or group id must be provided"); | |||
newRequest() | |||
.setParam(PARAM_PERMISSION, SYSTEM_ADMIN) | |||
@@ -220,16 +219,17 @@ public class RemoveGroupActionTest { | |||
@Test | |||
public void fail_when_permission_name_and_id_are_missing() throws Exception { | |||
expectedException.expect(IllegalArgumentException.class); | |||
expectedException.expectMessage("The 'permission' parameter is missing"); | |||
newRequest() | |||
.setParam(PARAM_GROUP_NAME, "sonar-administrators") | |||
.setParam(PARAM_GROUP_NAME, aGroup.getName()) | |||
.execute(); | |||
} | |||
@Test | |||
public void fail_when_group_id_does_not_exist() throws Exception { | |||
expectedException.expect(NotFoundException.class); | |||
expectedException.expectMessage("Group with id '42' is not found"); | |||
expectedException.expectMessage("No group with id '42'"); | |||
newRequest() | |||
.setParam(PARAM_PERMISSION, SYSTEM_ADMIN) | |||
@@ -239,32 +239,25 @@ public class RemoveGroupActionTest { | |||
@Test | |||
public void fail_when_project_uuid_and_project_key_are_provided() throws Exception { | |||
ComponentDto project = db.components().insertComponent(newProjectDto(A_PROJECT_UUID).setKey(A_PROJECT_KEY)); | |||
expectedException.expect(BadRequestException.class); | |||
expectedException.expectMessage("Project id or project key can be provided, not both."); | |||
insertComponent(newProjectDto("project-uuid").setKey("project-key")); | |||
commit(); | |||
newRequest() | |||
.setParam(PARAM_GROUP_NAME, "sonar-administrators") | |||
.setParam(PARAM_GROUP_NAME, aGroup.getName()) | |||
.setParam(PARAM_PERMISSION, SYSTEM_ADMIN) | |||
.setParam(PARAM_PROJECT_ID, "project-uuid") | |||
.setParam(PARAM_PROJECT_KEY, "project-key") | |||
.setParam(PARAM_PROJECT_ID, project.uuid()) | |||
.setParam(PARAM_PROJECT_KEY, project.getKey()) | |||
.execute(); | |||
} | |||
private WsTester.TestRequest newRequest() { | |||
return ws.newPostRequest(CONTROLLER, ACTION); | |||
} | |||
private GroupDto insertGroup(String groupName) { | |||
return db.getDbClient().groupDao().insert(dbSession, new GroupDto().setName(groupName)); | |||
return wsTester.newPostRequest(CONTROLLER, ACTION); | |||
} | |||
private void insertComponent(ComponentDto component) { | |||
db.getDbClient().componentDao().insert(dbSession, component); | |||
private void loginAsAdmin() { | |||
userSession.login("admin").setGlobalPermissions(SYSTEM_ADMIN); | |||
} | |||
private void commit() { | |||
dbSession.commit(); | |||
} | |||
} |
@@ -20,31 +20,19 @@ | |||
package org.sonar.server.permission.ws; | |||
import org.junit.Before; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.ExpectedException; | |||
import org.mockito.ArgumentCaptor; | |||
import org.sonar.api.resources.Qualifiers; | |||
import org.sonar.api.utils.System2; | |||
import org.sonar.api.web.UserRole; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.DbTester; | |||
import org.sonar.db.component.ComponentDto; | |||
import org.sonar.db.component.ResourceTypesRule; | |||
import org.sonar.server.component.ComponentFinder; | |||
import org.sonar.db.user.UserDto; | |||
import org.sonar.server.exceptions.BadRequestException; | |||
import org.sonar.server.exceptions.NotFoundException; | |||
import org.sonar.server.exceptions.ServerException; | |||
import org.sonar.server.permission.PermissionChange; | |||
import org.sonar.server.permission.PermissionUpdater; | |||
import org.sonar.server.tester.UserSessionRule; | |||
import org.sonar.server.usergroups.ws.UserGroupFinder; | |||
import org.sonar.server.ws.WsTester; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.verify; | |||
import static org.sonar.api.web.UserRole.ADMIN; | |||
import static org.sonar.api.web.UserRole.CODEVIEWER; | |||
import static org.sonar.api.web.UserRole.ISSUE_ADMIN; | |||
import static org.sonar.core.permission.GlobalPermissions.PROVISIONING; | |||
import static org.sonar.core.permission.GlobalPermissions.QUALITY_GATE_ADMIN; | |||
import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN; | |||
import static org.sonar.db.component.ComponentTesting.newFileDto; | |||
import static org.sonar.db.component.ComponentTesting.newProjectDto; | |||
@@ -56,117 +44,135 @@ import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_P | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PROJECT_KEY; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_USER_LOGIN; | |||
public class RemoveUserActionTest extends BasePermissionWsTest<RemoveUserAction> { | |||
public class RemoveUserActionTest { | |||
@Rule | |||
public DbTester db = DbTester.create(System2.INSTANCE); | |||
@Rule | |||
public ExpectedException expectedException = ExpectedException.none(); | |||
ResourceTypesRule resourceTypes = new ResourceTypesRule().setRootQualifiers(Qualifiers.PROJECT, Qualifiers.VIEW, "DEV"); | |||
UserSessionRule userSession = UserSessionRule.standalone(); | |||
WsTester ws; | |||
PermissionUpdater permissionUpdater; | |||
DbClient dbClient; | |||
DbSession dbSession; | |||
ArgumentCaptor<PermissionChange> permissionChangeCaptor = ArgumentCaptor.forClass(PermissionChange.class); | |||
private static final String A_PROJECT_UUID = "project-uuid"; | |||
private static final String A_PROJECT_KEY = "project-key"; | |||
private static final String A_LOGIN = "ray.bradbury"; | |||
private UserDto user; | |||
@Before | |||
public void setUp() { | |||
permissionUpdater = mock(PermissionUpdater.class); | |||
dbClient = db.getDbClient(); | |||
dbSession = db.getSession(); | |||
ComponentFinder componentFinder = new ComponentFinder(dbClient); | |||
ws = new WsTester(new PermissionsWs( | |||
new RemoveUserAction(dbClient, permissionUpdater, new PermissionChangeBuilder(new PermissionDependenciesFinder(dbClient, componentFinder, new UserGroupFinder(dbClient), resourceTypes))))); | |||
userSession.login("admin").setGlobalPermissions(SYSTEM_ADMIN); | |||
user = db.users().insertUser(A_LOGIN); | |||
} | |||
@Override | |||
protected RemoveUserAction buildWsAction() { | |||
return new RemoveUserAction(db.getDbClient(), newPermissionUpdater(), newPermissionWsSupport()); | |||
} | |||
@Test | |||
public void call_permission_service_with_right_data() throws Exception { | |||
ws.newPostRequest(CONTROLLER, ACTION) | |||
.setParam(PARAM_USER_LOGIN, "ray.bradbury") | |||
.setParam(PARAM_PERMISSION, SYSTEM_ADMIN) | |||
public void remove_permission_from_user() throws Exception { | |||
db.users().insertPermissionOnUser(user, PROVISIONING); | |||
db.users().insertPermissionOnUser(user, QUALITY_GATE_ADMIN); | |||
loginAsAdmin(); | |||
wsTester.newPostRequest(CONTROLLER, ACTION) | |||
.setParam(PARAM_USER_LOGIN, user.getLogin()) | |||
.setParam(PARAM_PERMISSION, QUALITY_GATE_ADMIN) | |||
.execute(); | |||
verify(permissionUpdater).removePermission(permissionChangeCaptor.capture()); | |||
PermissionChange permissionChange = permissionChangeCaptor.getValue(); | |||
assertThat(permissionChange.userLogin()).isEqualTo("ray.bradbury"); | |||
assertThat(permissionChange.permission()).isEqualTo(SYSTEM_ADMIN); | |||
assertThat(db.users().selectUserPermissions(user, null)).containsOnly(PROVISIONING); | |||
} | |||
@Test | |||
public void remove_with_project_uuid() throws Exception { | |||
insertComponent(newProjectDto("project-uuid").setKey("project-key")); | |||
public void fail_to_remove_admin_permission_if_last_admin() throws Exception { | |||
db.users().insertPermissionOnUser(user, CODEVIEWER); | |||
db.users().insertPermissionOnUser(user, ADMIN); | |||
loginAsAdmin(); | |||
ws.newPostRequest(CONTROLLER, ACTION) | |||
.setParam(PARAM_USER_LOGIN, "ray.bradbury") | |||
.setParam(PARAM_PROJECT_ID, "project-uuid") | |||
.setParam(PARAM_PERMISSION, SYSTEM_ADMIN) | |||
expectedException.expect(BadRequestException.class); | |||
expectedException.expectMessage("Last user with 'admin' permission. Permission cannot be removed."); | |||
wsTester.newPostRequest(CONTROLLER, ACTION) | |||
.setParam(PARAM_USER_LOGIN, user.getLogin()) | |||
.setParam(PARAM_PERMISSION, ADMIN) | |||
.execute(); | |||
} | |||
@Test | |||
public void remove_permission_from_project() throws Exception { | |||
ComponentDto project = db.components().insertComponent(newProjectDto(A_PROJECT_UUID).setKey(A_PROJECT_KEY)); | |||
db.users().insertProjectPermissionOnUser(user, CODEVIEWER, project); | |||
db.users().insertProjectPermissionOnUser(user, ISSUE_ADMIN, project); | |||
loginAsAdmin(); | |||
wsTester.newPostRequest(CONTROLLER, ACTION) | |||
.setParam(PARAM_USER_LOGIN, user.getLogin()) | |||
.setParam(PARAM_PROJECT_ID, project.uuid()) | |||
.setParam(PARAM_PERMISSION, CODEVIEWER) | |||
.execute(); | |||
verify(permissionUpdater).removePermission(permissionChangeCaptor.capture()); | |||
PermissionChange permissionChange = permissionChangeCaptor.getValue(); | |||
assertThat(permissionChange.componentKey()).isEqualTo("project-key"); | |||
assertThat(db.users().selectUserPermissions(user, project)).containsOnly(ISSUE_ADMIN); | |||
} | |||
@Test | |||
public void remove_with_project_key() throws Exception { | |||
insertComponent(newProjectDto("project-uuid").setKey("project-key")); | |||
ws.newPostRequest(CONTROLLER, ACTION) | |||
.setParam(PARAM_USER_LOGIN, "ray.bradbury") | |||
.setParam(PARAM_PROJECT_KEY, "project-key") | |||
.setParam(PARAM_PERMISSION, SYSTEM_ADMIN) | |||
ComponentDto project = db.components().insertComponent(newProjectDto(A_PROJECT_UUID).setKey(A_PROJECT_KEY)); | |||
db.users().insertProjectPermissionOnUser(user, ISSUE_ADMIN, project); | |||
db.users().insertProjectPermissionOnUser(user, CODEVIEWER, project); | |||
loginAsAdmin(); | |||
wsTester.newPostRequest(CONTROLLER, ACTION) | |||
.setParam(PARAM_USER_LOGIN, user.getLogin()) | |||
.setParam(PARAM_PROJECT_KEY, project.getKey()) | |||
.setParam(PARAM_PERMISSION, ISSUE_ADMIN) | |||
.execute(); | |||
verify(permissionUpdater).removePermission(permissionChangeCaptor.capture()); | |||
PermissionChange permissionChange = permissionChangeCaptor.getValue(); | |||
assertThat(permissionChange.componentKey()).isEqualTo("project-key"); | |||
assertThat(db.users().selectUserPermissions(user, project)).containsOnly(CODEVIEWER); | |||
} | |||
@Test | |||
public void remove_with_view_uuid() throws Exception { | |||
insertComponent(newView("view-uuid").setKey("view-key")); | |||
ws.newPostRequest(CONTROLLER, ACTION) | |||
.setParam(PARAM_USER_LOGIN, "ray.bradbury") | |||
.setParam(PARAM_PROJECT_ID, "view-uuid") | |||
.setParam(PARAM_PERMISSION, SYSTEM_ADMIN) | |||
ComponentDto view = db.components().insertComponent(newView("view-uuid").setKey("view-key")); | |||
db.users().insertProjectPermissionOnUser(user, ISSUE_ADMIN, view); | |||
db.users().insertProjectPermissionOnUser(user, CODEVIEWER, view); | |||
loginAsAdmin(); | |||
wsTester.newPostRequest(CONTROLLER, ACTION) | |||
.setParam(PARAM_USER_LOGIN, user.getLogin()) | |||
.setParam(PARAM_PROJECT_KEY, view.getKey()) | |||
.setParam(PARAM_PERMISSION, ISSUE_ADMIN) | |||
.execute(); | |||
verify(permissionUpdater).removePermission(permissionChangeCaptor.capture()); | |||
PermissionChange permissionChange = permissionChangeCaptor.getValue(); | |||
assertThat(permissionChange.componentKey()).isEqualTo("view-key"); | |||
assertThat(db.users().selectUserPermissions(user, view)).containsOnly(CODEVIEWER); | |||
} | |||
@Test | |||
public void fail_when_project_does_not_exist() throws Exception { | |||
loginAsAdmin(); | |||
expectedException.expect(NotFoundException.class); | |||
ws.newPostRequest(CONTROLLER, ACTION) | |||
.setParam(PARAM_USER_LOGIN, "ray.bradbury") | |||
wsTester.newPostRequest(CONTROLLER, ACTION) | |||
.setParam(PARAM_USER_LOGIN, user.getLogin()) | |||
.setParam(PARAM_PROJECT_ID, "unknown-project-uuid") | |||
.setParam(PARAM_PERMISSION, UserRole.ISSUE_ADMIN) | |||
.setParam(PARAM_PERMISSION, ISSUE_ADMIN) | |||
.execute(); | |||
} | |||
@Test | |||
public void fail_when_project_permission_without_permission() throws Exception { | |||
loginAsAdmin(); | |||
expectedException.expect(BadRequestException.class); | |||
ws.newPostRequest(CONTROLLER, ACTION) | |||
.setParam(PARAM_USER_LOGIN, "ray.bradbury") | |||
.setParam(PARAM_PERMISSION, UserRole.ISSUE_ADMIN) | |||
wsTester.newPostRequest(CONTROLLER, ACTION) | |||
.setParam(PARAM_USER_LOGIN, user.getLogin()) | |||
.setParam(PARAM_PERMISSION, ISSUE_ADMIN) | |||
.execute(); | |||
} | |||
@Test | |||
public void fail_when_component_is_not_a_project() throws Exception { | |||
db.components().insertComponent(newFileDto(newProjectDto(), null, "file-uuid")); | |||
loginAsAdmin(); | |||
expectedException.expect(BadRequestException.class); | |||
insertComponent(newFileDto(newProjectDto(), null, "file-uuid")); | |||
ws.newPostRequest(CONTROLLER, ACTION) | |||
.setParam(PARAM_USER_LOGIN, "ray.bradbury") | |||
wsTester.newPostRequest(CONTROLLER, ACTION) | |||
.setParam(PARAM_USER_LOGIN, user.getLogin()) | |||
.setParam(PARAM_PROJECT_ID, "file-uuid") | |||
.setParam(PARAM_PERMISSION, SYSTEM_ADMIN) | |||
.execute(); | |||
@@ -174,9 +180,11 @@ public class RemoveUserActionTest { | |||
@Test | |||
public void fail_when_get_request() throws Exception { | |||
loginAsAdmin(); | |||
expectedException.expect(ServerException.class); | |||
ws.newGetRequest(CONTROLLER, ACTION) | |||
wsTester.newGetRequest(CONTROLLER, ACTION) | |||
.setParam(PARAM_USER_LOGIN, "george.orwell") | |||
.setParam(PARAM_PERMISSION, SYSTEM_ADMIN) | |||
.execute(); | |||
@@ -184,38 +192,43 @@ public class RemoveUserActionTest { | |||
@Test | |||
public void fail_when_user_login_is_missing() throws Exception { | |||
loginAsAdmin(); | |||
expectedException.expect(IllegalArgumentException.class); | |||
ws.newPostRequest(CONTROLLER, ACTION) | |||
wsTester.newPostRequest(CONTROLLER, ACTION) | |||
.setParam(PARAM_PERMISSION, SYSTEM_ADMIN) | |||
.execute(); | |||
} | |||
@Test | |||
public void fail_when_permission_is_missing() throws Exception { | |||
loginAsAdmin(); | |||
expectedException.expect(IllegalArgumentException.class); | |||
ws.newPostRequest(CONTROLLER, ACTION) | |||
.setParam(PARAM_USER_LOGIN, "jrr.tolkien") | |||
wsTester.newPostRequest(CONTROLLER, ACTION) | |||
.setParam(PARAM_USER_LOGIN, user.getLogin()) | |||
.execute(); | |||
} | |||
@Test | |||
public void fail_when_project_uuid_and_project_key_are_provided() throws Exception { | |||
ComponentDto project = db.components().insertComponent(newProjectDto(A_PROJECT_UUID).setKey(A_PROJECT_KEY)); | |||
loginAsAdmin(); | |||
expectedException.expect(BadRequestException.class); | |||
expectedException.expectMessage("Project id or project key can be provided, not both."); | |||
insertComponent(newProjectDto("project-uuid").setKey("project-key")); | |||
ws.newPostRequest(CONTROLLER, ACTION) | |||
wsTester.newPostRequest(CONTROLLER, ACTION) | |||
.setParam(PARAM_PERMISSION, SYSTEM_ADMIN) | |||
.setParam(PARAM_USER_LOGIN, "ray.bradbury") | |||
.setParam(PARAM_PROJECT_ID, "project-uuid") | |||
.setParam(PARAM_PROJECT_KEY, "project-key") | |||
.setParam(PARAM_USER_LOGIN, user.getLogin()) | |||
.setParam(PARAM_PROJECT_ID, project.uuid()) | |||
.setParam(PARAM_PROJECT_KEY, project.getKey()) | |||
.execute(); | |||
} | |||
private void insertComponent(ComponentDto component) { | |||
dbClient.componentDao().insert(dbSession, component); | |||
dbSession.commit(); | |||
private void loginAsAdmin() { | |||
userSession.login("admin").setGlobalPermissions(SYSTEM_ADMIN); | |||
} | |||
} |
@@ -20,17 +20,16 @@ | |||
package org.sonar.server.permission.ws; | |||
import java.io.IOException; | |||
import javax.annotation.Nullable; | |||
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.db.DbTester; | |||
import org.sonar.db.permission.GroupPermissionDto; | |||
import org.sonar.db.permission.UserPermissionDto; | |||
import org.sonar.db.user.GroupDto; | |||
import org.sonar.db.user.GroupTesting; | |||
import org.sonar.db.user.UserDto; | |||
import org.sonar.db.user.UserTesting; | |||
import org.sonar.server.exceptions.ForbiddenException; | |||
import org.sonar.server.exceptions.UnauthorizedException; | |||
import org.sonar.server.i18n.I18nRule; | |||
@@ -55,8 +54,8 @@ public class SearchGlobalPermissionsActionTest { | |||
public DbTester db = DbTester.create(System2.INSTANCE); | |||
@Rule | |||
public UserSessionRule userSession = UserSessionRule.standalone(); | |||
WsActionTester ws; | |||
I18nRule i18n = new I18nRule(); | |||
private WsActionTester ws; | |||
private I18nRule i18n = new I18nRule(); | |||
@Before | |||
public void setUp() { | |||
@@ -68,22 +67,19 @@ public class SearchGlobalPermissionsActionTest { | |||
@Test | |||
public void search() { | |||
GroupDto adminGroup = insertGroup(newGroupDto("sonar-admins", "Administrators")); | |||
GroupDto userGroup = insertGroup(newGroupDto("sonar-users", "Users")); | |||
insertGroupRole(newGroupRole(SCAN_EXECUTION, null)); | |||
insertGroupRole(newGroupRole(SCAN_EXECUTION, userGroup.getId())); | |||
insertGroupRole(newGroupRole(SYSTEM_ADMIN, adminGroup.getId())); | |||
insertGroupRole(newGroupRole(PROVISIONING, userGroup.getId())); | |||
UserDto user = insertUser(newUserDto("user", "user-name")); | |||
UserDto adminUser = insertUser(newUserDto("admin", "admin-name")); | |||
insertUserPermission(newUserPermission(PROVISIONING, user.getId())); | |||
insertUserPermission(newUserPermission(QUALITY_PROFILE_ADMIN, user.getId())); | |||
insertUserPermission(newUserPermission(QUALITY_PROFILE_ADMIN, adminUser.getId())); | |||
insertUserPermission(newUserPermission(QUALITY_GATE_ADMIN, user.getId())); | |||
insertUserPermission(newUserPermission(QUALITY_GATE_ADMIN, adminUser.getId())); | |||
db.getSession().commit(); | |||
GroupDto adminGroup = db.users().insertGroup(newGroupDto("sonar-admins", "Administrators")); | |||
GroupDto userGroup = db.users().insertGroup(newGroupDto("sonar-users", "Users")); | |||
db.users().insertPermissionOnAnyone(SCAN_EXECUTION); | |||
db.users().insertPermissionOnGroup(userGroup, SCAN_EXECUTION); | |||
db.users().insertPermissionOnGroup(userGroup, PROVISIONING); | |||
db.users().insertPermissionOnGroup(adminGroup, SYSTEM_ADMIN); | |||
UserDto user = db.users().insertUser(newUserDto("user", "user-name")); | |||
UserDto adminUser = db.users().insertUser(newUserDto("admin", "admin-name")); | |||
db.users().insertPermissionOnUser(user, PROVISIONING); | |||
db.users().insertPermissionOnUser(user, QUALITY_PROFILE_ADMIN); | |||
db.users().insertPermissionOnUser(adminUser, QUALITY_PROFILE_ADMIN); | |||
db.users().insertPermissionOnUser(user, QUALITY_GATE_ADMIN); | |||
db.users().insertPermissionOnUser(adminUser, QUALITY_GATE_ADMIN); | |||
String result = ws.newRequest().execute().getInput(); | |||
@@ -102,17 +98,19 @@ public class SearchGlobalPermissionsActionTest { | |||
@Test | |||
public void fail_if_insufficient_privileges() { | |||
expectedException.expect(ForbiddenException.class); | |||
userSession.login("login"); | |||
expectedException.expect(ForbiddenException.class); | |||
ws.newRequest().execute(); | |||
} | |||
@Test | |||
public void fail_if_not_logged_in() { | |||
expectedException.expect(UnauthorizedException.class); | |||
userSession.anonymous(); | |||
expectedException.expect(UnauthorizedException.class); | |||
ws.newRequest().execute(); | |||
} | |||
@@ -131,40 +129,11 @@ public class SearchGlobalPermissionsActionTest { | |||
i18n.put("global_permissions.provisioning.desc", "Ability to initialize project structure before first analysis."); | |||
} | |||
private UserDto insertUser(UserDto user) { | |||
return db.getDbClient().userDao().insert(db.getSession(), user); | |||
} | |||
private void insertUserPermission(UserPermissionDto dto) { | |||
db.getDbClient().userPermissionDao().insert(db.getSession(), dto); | |||
} | |||
private GroupDto insertGroup(GroupDto groupDto) { | |||
return db.getDbClient().groupDao().insert(db.getSession(), groupDto); | |||
} | |||
private void insertGroupRole(GroupPermissionDto group) { | |||
db.getDbClient().roleDao().insertGroupRole(db.getSession(), group); | |||
} | |||
private static UserDto newUserDto(String login, String name) { | |||
return new UserDto().setLogin(login).setName(name).setActive(true); | |||
return UserTesting.newUserDto().setLogin(login).setName(name).setActive(true); | |||
} | |||
private static GroupDto newGroupDto(String name, String description) { | |||
return new GroupDto().setName(name).setDescription(description); | |||
} | |||
private static GroupPermissionDto newGroupRole(String role, @Nullable Long groupId) { | |||
GroupPermissionDto groupRole = new GroupPermissionDto().setRole(role); | |||
if (groupId != null) { | |||
groupRole.setGroupId(groupId); | |||
} | |||
return groupRole; | |||
} | |||
private static UserPermissionDto newUserPermission(String permission, long userId) { | |||
return new UserPermissionDto(permission, userId, null); | |||
return GroupTesting.newGroupDto().setName(name).setDescription(description); | |||
} | |||
} |
@@ -19,36 +19,22 @@ | |||
*/ | |||
package org.sonar.server.permission.ws; | |||
import java.io.IOException; | |||
import javax.annotation.Nullable; | |||
import org.junit.Before; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.ExpectedException; | |||
import org.sonar.api.resources.Qualifiers; | |||
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.component.ComponentDbTester; | |||
import org.sonar.db.component.ComponentDto; | |||
import org.sonar.db.component.ResourceTypesRule; | |||
import org.sonar.db.permission.GroupPermissionDto; | |||
import org.sonar.db.permission.UserPermissionDto; | |||
import org.sonar.db.user.GroupDto; | |||
import org.sonar.db.user.UserDto; | |||
import org.sonar.server.component.ComponentFinder; | |||
import org.sonar.server.exceptions.ForbiddenException; | |||
import org.sonar.server.exceptions.UnauthorizedException; | |||
import org.sonar.server.i18n.I18nRule; | |||
import org.sonar.server.tester.UserSessionRule; | |||
import org.sonar.server.usergroups.ws.UserGroupFinder; | |||
import org.sonar.server.ws.TestResponse; | |||
import org.sonar.server.ws.WsActionTester; | |||
import org.sonar.server.ws.WsTester; | |||
import org.sonarqube.ws.MediaTypes; | |||
import org.sonarqube.ws.WsPermissions.SearchProjectPermissionsWsResponse; | |||
import org.sonarqube.ws.WsPermissions; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.sonar.api.server.ws.WebService.Param.PAGE; | |||
@@ -59,49 +45,35 @@ import static org.sonar.db.component.ComponentTesting.newProjectCopy; | |||
import static org.sonar.db.component.ComponentTesting.newProjectDto; | |||
import static org.sonar.db.component.ComponentTesting.newView; | |||
import static org.sonar.db.user.GroupTesting.newGroupDto; | |||
import static org.sonar.db.user.UserTesting.newUserDto; | |||
import static org.sonar.test.JsonAssert.assertJson; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.CONTROLLER; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PROJECT_ID; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_QUALIFIER; | |||
public class SearchProjectPermissionsActionTest { | |||
@Rule | |||
public ExpectedException expectedException = ExpectedException.none(); | |||
@Rule | |||
public UserSessionRule userSession = UserSessionRule.standalone(); | |||
@Rule | |||
public DbTester db = DbTester.create(System2.INSTANCE); | |||
ComponentDbTester componentDb = new ComponentDbTester(db); | |||
public class SearchProjectPermissionsActionTest extends BasePermissionWsTest<SearchProjectPermissionsAction> { | |||
WsActionTester ws; | |||
I18nRule i18n = new I18nRule(); | |||
DbClient dbClient = db.getDbClient(); | |||
final DbSession dbSession = db.getSession(); | |||
ResourceTypesRule resourceTypes = new ResourceTypesRule(); | |||
SearchProjectPermissionsDataLoader dataLoader; | |||
SearchProjectPermissionsAction underTest; | |||
private ComponentDbTester componentDb = new ComponentDbTester(db); | |||
private I18nRule i18n = new I18nRule(); | |||
@Before | |||
public void setUp() { | |||
resourceTypes.setRootQualifiers(Qualifiers.PROJECT, Qualifiers.VIEW, "DEV"); | |||
ComponentFinder componentFinder = new ComponentFinder(dbClient); | |||
PermissionDependenciesFinder finder = new PermissionDependenciesFinder(dbClient, componentFinder, new UserGroupFinder(dbClient), resourceTypes); | |||
i18n.setProjectPermissions(); | |||
dataLoader = new SearchProjectPermissionsDataLoader(dbClient, finder, resourceTypes); | |||
underTest = new SearchProjectPermissionsAction(dbClient, userSession, i18n, resourceTypes, dataLoader); | |||
ws = new WsActionTester(underTest); | |||
userSession.login().setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); | |||
} | |||
@Override | |||
protected SearchProjectPermissionsAction buildWsAction() { | |||
i18n.setProjectPermissions(); | |||
ResourceTypesRule rootResourceTypes = newRootResourceTypes(); | |||
SearchProjectPermissionsDataLoader dataLoader = new SearchProjectPermissionsDataLoader(db.getDbClient(), newPermissionWsSupport(), rootResourceTypes); | |||
return new SearchProjectPermissionsAction(db.getDbClient(), userSession, i18n, rootResourceTypes, dataLoader); | |||
} | |||
@Test | |||
public void search_project_permissions() { | |||
UserDto user1 = insertUser(newUserDto()); | |||
UserDto user2 = insertUser(newUserDto()); | |||
UserDto user3 = insertUser(newUserDto()); | |||
public void search_project_permissions() throws Exception { | |||
UserDto user1 = db.users().insertUser(); | |||
UserDto user2 = db.users().insertUser(); | |||
UserDto user3 = db.users().insertUser(); | |||
ComponentDto jdk7 = insertJdk7(); | |||
ComponentDto project2 = insertClang(); | |||
@@ -109,30 +81,30 @@ public class SearchProjectPermissionsActionTest { | |||
ComponentDto view = insertView(); | |||
insertProjectInView(jdk7, view); | |||
insertUserPermission(UserRole.ISSUE_ADMIN, user1.getId(), jdk7.getId()); | |||
insertUserPermission(UserRole.ADMIN, user1.getId(), jdk7.getId()); | |||
insertUserPermission(UserRole.ADMIN, user2.getId(), jdk7.getId()); | |||
insertUserPermission(UserRole.ADMIN, user3.getId(), jdk7.getId()); | |||
insertUserPermission(UserRole.ISSUE_ADMIN, user1.getId(), project2.getId()); | |||
insertUserPermission(UserRole.ISSUE_ADMIN, user1.getId(), dev.getId()); | |||
insertUserPermission(UserRole.ISSUE_ADMIN, user1.getId(), view.getId()); | |||
db.users().insertProjectPermissionOnUser(user1, UserRole.ISSUE_ADMIN, jdk7); | |||
db.users().insertProjectPermissionOnUser(user1, UserRole.ADMIN, jdk7); | |||
db.users().insertProjectPermissionOnUser(user2, UserRole.ADMIN, jdk7); | |||
db.users().insertProjectPermissionOnUser(user3, UserRole.ADMIN, jdk7); | |||
db.users().insertProjectPermissionOnUser(user1, UserRole.ISSUE_ADMIN, project2); | |||
db.users().insertProjectPermissionOnUser(user1, UserRole.ISSUE_ADMIN, dev); | |||
db.users().insertProjectPermissionOnUser(user1, UserRole.ISSUE_ADMIN, view); | |||
// global permission | |||
insertUserPermission(GlobalPermissions.SYSTEM_ADMIN, user1.getId(), null); | |||
db.users().insertPermissionOnUser(user1, GlobalPermissions.SYSTEM_ADMIN); | |||
GroupDto group1 = insertGroup(newGroupDto()); | |||
GroupDto group2 = insertGroup(newGroupDto()); | |||
GroupDto group3 = insertGroup(newGroupDto()); | |||
GroupDto group1 = db.users().insertGroup(newGroupDto()); | |||
GroupDto group2 = db.users().insertGroup(newGroupDto()); | |||
GroupDto group3 = db.users().insertGroup(newGroupDto()); | |||
insertGroupRole(UserRole.ADMIN, jdk7.getId(), null); | |||
insertGroupRole(UserRole.ADMIN, jdk7.getId(), group1.getId()); | |||
insertGroupRole(UserRole.ADMIN, jdk7.getId(), group2.getId()); | |||
insertGroupRole(UserRole.ADMIN, jdk7.getId(), group3.getId()); | |||
insertGroupRole(UserRole.ADMIN, dev.getId(), group2.getId()); | |||
insertGroupRole(UserRole.ADMIN, view.getId(), group2.getId()); | |||
db.users().insertProjectPermissionOnAnyone(defaultOrganizationProvider.getDto(), UserRole.ADMIN, jdk7); | |||
db.users().insertProjectPermissionOnGroup(group1, UserRole.ADMIN, jdk7); | |||
db.users().insertProjectPermissionOnGroup(group2, UserRole.ADMIN, jdk7); | |||
db.users().insertProjectPermissionOnGroup(group3, UserRole.ADMIN, jdk7); | |||
db.users().insertProjectPermissionOnGroup(group2, UserRole.ADMIN, dev); | |||
db.users().insertProjectPermissionOnGroup(group2, UserRole.ADMIN, view); | |||
commit(); | |||
db.commit(); | |||
String result = ws.newRequest().execute().getInput(); | |||
String result = newRequest().execute().outputAsString(); | |||
assertJson(result) | |||
.ignoreFields("permissions") | |||
@@ -140,8 +112,8 @@ public class SearchProjectPermissionsActionTest { | |||
} | |||
@Test | |||
public void empty_result() { | |||
String result = ws.newRequest().execute().getInput(); | |||
public void empty_result() throws Exception { | |||
String result = newRequest().execute().outputAsString(); | |||
assertJson(result) | |||
.ignoreFields("permissions") | |||
@@ -149,30 +121,28 @@ public class SearchProjectPermissionsActionTest { | |||
} | |||
@Test | |||
public void search_project_permissions_with_project_permission() { | |||
public void search_project_permissions_with_project_permission() throws Exception { | |||
userSession.login().addProjectUuidPermissions(UserRole.ADMIN, "project-uuid"); | |||
insertComponent(newProjectDto("project-uuid")); | |||
commit(); | |||
db.components().insertComponent(newProjectDto("project-uuid")); | |||
String result = ws.newRequest() | |||
String result = newRequest() | |||
.setParam(PARAM_PROJECT_ID, "project-uuid") | |||
.execute().getInput(); | |||
.execute().outputAsString(); | |||
assertThat(result).contains("project-uuid"); | |||
} | |||
@Test | |||
public void has_projects_ordered_by_name() { | |||
public void has_projects_ordered_by_name() throws Exception { | |||
for (int i = 9; i >= 1; i--) { | |||
insertComponent(newProjectDto() | |||
db.components().insertComponent(newProjectDto() | |||
.setName("project-name-" + i)); | |||
} | |||
commit(); | |||
String result = ws.newRequest() | |||
String result = newRequest() | |||
.setParam(PAGE, "1") | |||
.setParam(PAGE_SIZE, "3") | |||
.execute().getInput(); | |||
.execute().outputAsString(); | |||
assertThat(result) | |||
.contains("project-name-1", "project-name-2", "project-name-3") | |||
@@ -180,80 +150,62 @@ public class SearchProjectPermissionsActionTest { | |||
} | |||
@Test | |||
public void search_by_query_on_name() { | |||
public void search_by_query_on_name() throws Exception { | |||
componentDb.insertProjectAndSnapshot(newProjectDto().setName("project-name")); | |||
componentDb.insertProjectAndSnapshot(newProjectDto().setName("another-name")); | |||
componentDb.indexAllComponents(); | |||
String result = ws.newRequest() | |||
String result = newRequest() | |||
.setParam(TEXT_QUERY, "project") | |||
.execute().getInput(); | |||
.execute().outputAsString(); | |||
assertThat(result).contains("project-name") | |||
.doesNotContain("another-name"); | |||
} | |||
@Test | |||
public void search_by_query_on_key_must_match_exactly() { | |||
public void search_by_query_on_key_must_match_exactly() throws Exception { | |||
componentDb.insertProjectAndSnapshot(newProjectDto().setKey("project-key")); | |||
componentDb.insertProjectAndSnapshot(newProjectDto().setKey("another-key")); | |||
componentDb.indexAllComponents(); | |||
String result = ws.newRequest() | |||
String result = newRequest() | |||
.setParam(TEXT_QUERY, "project-key") | |||
.execute().getInput(); | |||
.execute() | |||
.outputAsString(); | |||
assertThat(result).contains("project-key") | |||
.doesNotContain("another-key"); | |||
} | |||
@Test | |||
public void handle_more_than_1000_projects() { | |||
public void handle_more_than_1000_projects() throws Exception { | |||
for (int i = 1; i <= 1001; i++) { | |||
componentDb.insertProjectAndSnapshot(newProjectDto("project-uuid-" + i)); | |||
} | |||
componentDb.indexAllComponents(); | |||
String result = ws.newRequest() | |||
String result = newRequest() | |||
.setParam(TEXT_QUERY, "project") | |||
.setParam(PAGE_SIZE, "1001") | |||
.execute().getInput(); | |||
.execute() | |||
.outputAsString(); | |||
assertThat(result).contains("project-uuid-1", "project-uuid-999", "project-uuid-1001"); | |||
} | |||
@Test | |||
public void result_depends_of_root_types() { | |||
resourceTypes.setRootQualifiers(Qualifiers.PROJECT); | |||
insertComponent(newView("view-uuid")); | |||
insertComponent(newDeveloper("developer-name")); | |||
insertComponent(newProjectDto("project-uuid")); | |||
commit(); | |||
dataLoader = new SearchProjectPermissionsDataLoader(dbClient, | |||
new PermissionDependenciesFinder(dbClient, new ComponentFinder(dbClient), new UserGroupFinder(dbClient), resourceTypes), | |||
resourceTypes); | |||
underTest = new SearchProjectPermissionsAction(dbClient, userSession, i18n, resourceTypes, dataLoader); | |||
ws = new WsActionTester(underTest); | |||
String result = ws.newRequest().execute().getInput(); | |||
assertThat(result).contains("project-uuid") | |||
.doesNotContain("view-uuid") | |||
.doesNotContain("developer-name"); | |||
} | |||
public void filter_by_qualifier() throws Exception { | |||
db.components().insertComponent(newView("view-uuid")); | |||
db.components().insertComponent(newDeveloper("developer-name")); | |||
db.components().insertComponent(newProjectDto("project-uuid")); | |||
@Test | |||
public void filter_by_qualifier() throws IOException { | |||
insertComponent(newView("view-uuid")); | |||
insertComponent(newDeveloper("developer-name")); | |||
insertComponent(newProjectDto("project-uuid")); | |||
commit(); | |||
TestResponse wsResponse = ws.newRequest() | |||
byte[] wsResponse = newRequest() | |||
.setMediaType(MediaTypes.PROTOBUF) | |||
.setParam(PARAM_QUALIFIER, Qualifiers.PROJECT) | |||
.execute(); | |||
SearchProjectPermissionsWsResponse result = SearchProjectPermissionsWsResponse.parseFrom(wsResponse.getInputStream()); | |||
.execute() | |||
.output(); | |||
WsPermissions.SearchProjectPermissionsWsResponse result = WsPermissions.SearchProjectPermissionsWsResponse.parseFrom(wsResponse); | |||
assertThat(result.getProjectsList()) | |||
.extracting("id") | |||
@@ -263,24 +215,26 @@ public class SearchProjectPermissionsActionTest { | |||
} | |||
@Test | |||
public void fail_if_not_logged_in() { | |||
expectedException.expect(UnauthorizedException.class); | |||
public void fail_if_not_logged_in() throws Exception { | |||
userSession.anonymous(); | |||
ws.newRequest().execute(); | |||
expectedException.expect(UnauthorizedException.class); | |||
newRequest().execute(); | |||
} | |||
@Test | |||
public void fail_if_not_admin() { | |||
expectedException.expect(ForbiddenException.class); | |||
public void fail_if_not_admin() throws Exception { | |||
userSession.login(); | |||
ws.newRequest().execute(); | |||
expectedException.expect(ForbiddenException.class); | |||
newRequest().execute(); | |||
} | |||
@Test | |||
public void display_all_project_permissions() { | |||
String result = ws.newRequest().execute().getInput(); | |||
public void display_all_project_permissions() throws Exception { | |||
String result = newRequest().execute().outputAsString(); | |||
assertJson(result) | |||
.ignoreFields("permissions") | |||
@@ -288,58 +242,37 @@ public class SearchProjectPermissionsActionTest { | |||
} | |||
private ComponentDto insertView() { | |||
return insertComponent(newView() | |||
return db.components().insertComponent(newView() | |||
.setUuid("752d8bfd-420c-4a83-a4e5-8ab19b13c8fc") | |||
.setName("Java") | |||
.setKey("Java")); | |||
} | |||
private ComponentDto insertProjectInView(ComponentDto project, ComponentDto view) { | |||
return insertComponent(newProjectCopy("project-in-view-uuid", project, view)); | |||
return db.components().insertComponent(newProjectCopy("project-in-view-uuid", project, view)); | |||
} | |||
private ComponentDto insertDeveloper() { | |||
return insertComponent(newDeveloper("Simon Brandhof") | |||
return db.components().insertComponent(newDeveloper("Simon Brandhof") | |||
.setUuid("4e607bf9-7ed0-484a-946d-d58ba7dab2fb") | |||
.setKey("simon-brandhof")); | |||
} | |||
private ComponentDto insertClang() { | |||
return insertComponent(newProjectDto("project-uuid-2") | |||
return db.components().insertComponent(newProjectDto("project-uuid-2") | |||
.setName("Clang") | |||
.setKey("clang") | |||
.setUuid("ce4c03d6-430f-40a9-b777-ad877c00aa4d")); | |||
} | |||
private ComponentDto insertJdk7() { | |||
return insertComponent(newProjectDto("project-uuid-1") | |||
return db.components().insertComponent(newProjectDto("project-uuid-1") | |||
.setName("JDK 7") | |||
.setKey("net.java.openjdk:jdk7") | |||
.setUuid("0bd7b1e7-91d6-439e-a607-4a3a9aad3c6a")); | |||
} | |||
private UserDto insertUser(UserDto user) { | |||
return dbClient.userDao().insert(dbSession, user.setActive(true)); | |||
} | |||
private void insertUserPermission(String permission, long userId, @Nullable Long resourceId) { | |||
dbClient.userPermissionDao().insert(dbSession, new UserPermissionDto(permission, userId, resourceId)); | |||
} | |||
private GroupDto insertGroup(GroupDto group) { | |||
return dbClient.groupDao().insert(dbSession, group); | |||
} | |||
private void insertGroupRole(String permission, @Nullable Long resourceId, @Nullable Long groupId) { | |||
dbClient.roleDao().insertGroupRole(dbSession, new GroupPermissionDto().setRole(permission).setResourceId(resourceId).setGroupId(groupId)); | |||
} | |||
private ComponentDto insertComponent(ComponentDto component) { | |||
dbClient.componentDao().insert(dbSession, component.setEnabled(true)); | |||
return dbClient.componentDao().selectOrFailByUuid(dbSession, component.uuid()); | |||
} | |||
private void commit() { | |||
dbSession.commit(); | |||
private WsTester.TestRequest newRequest() { | |||
return wsTester.newPostRequest(CONTROLLER, "search_project_permissions"); | |||
} | |||
} |
@@ -25,7 +25,6 @@ import java.util.Collections; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.ExpectedException; | |||
import org.sonar.db.component.ComponentDto; | |||
public class SearchProjectPermissionsDataTest { | |||
@Rule | |||
@@ -36,8 +35,8 @@ public class SearchProjectPermissionsDataTest { | |||
expectedException.expect(IllegalStateException.class); | |||
SearchProjectPermissionsData.newBuilder() | |||
.groupCountByProjectIdAndPermission(HashBasedTable.<Long, String, Integer>create()) | |||
.userCountByProjectIdAndPermission(HashBasedTable.<Long, String, Integer>create()) | |||
.groupCountByProjectIdAndPermission(HashBasedTable.create()) | |||
.userCountByProjectIdAndPermission(HashBasedTable.create()) | |||
.build(); | |||
} | |||
@@ -46,8 +45,8 @@ public class SearchProjectPermissionsDataTest { | |||
expectedException.expect(IllegalStateException.class); | |||
SearchProjectPermissionsData.newBuilder() | |||
.rootComponents(Collections.<ComponentDto>emptyList()) | |||
.userCountByProjectIdAndPermission(HashBasedTable.<Long, String, Integer>create()) | |||
.rootComponents(Collections.emptyList()) | |||
.userCountByProjectIdAndPermission(HashBasedTable.create()) | |||
.build(); | |||
} | |||
@@ -56,8 +55,8 @@ public class SearchProjectPermissionsDataTest { | |||
expectedException.expect(IllegalStateException.class); | |||
SearchProjectPermissionsData.newBuilder() | |||
.rootComponents(Collections.<ComponentDto>emptyList()) | |||
.groupCountByProjectIdAndPermission(HashBasedTable.<Long, String, Integer>create()) | |||
.rootComponents(Collections.emptyList()) | |||
.groupCountByProjectIdAndPermission(HashBasedTable.create()) | |||
.build(); | |||
} | |||
} |
@@ -1,358 +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.permission.ws; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import javax.annotation.Nullable; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.ExpectedException; | |||
import org.sonar.api.resources.Qualifiers; | |||
import org.sonar.api.server.ws.WebService; | |||
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.component.ResourceTypesRule; | |||
import org.sonar.db.permission.template.PermissionTemplateDto; | |||
import org.sonar.db.permission.template.PermissionTemplateUserDto; | |||
import org.sonar.db.user.UserDto; | |||
import org.sonar.server.component.ComponentFinder; | |||
import org.sonar.server.exceptions.BadRequestException; | |||
import org.sonar.server.exceptions.ForbiddenException; | |||
import org.sonar.server.exceptions.NotFoundException; | |||
import org.sonar.server.exceptions.UnauthorizedException; | |||
import org.sonar.server.tester.UserSessionRule; | |||
import org.sonar.server.usergroups.ws.UserGroupFinder; | |||
import org.sonar.server.ws.TestRequest; | |||
import org.sonar.server.ws.WsActionTester; | |||
import org.sonarqube.ws.WsPermissions; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.sonar.api.web.UserRole.ADMIN; | |||
import static org.sonar.api.web.UserRole.CODEVIEWER; | |||
import static org.sonar.api.web.UserRole.ISSUE_ADMIN; | |||
import static org.sonar.api.web.UserRole.USER; | |||
import static org.sonar.db.permission.template.PermissionTemplateTesting.newPermissionTemplateDto; | |||
import static org.sonar.db.permission.template.PermissionTemplateTesting.newPermissionTemplateUserDto; | |||
import static org.sonar.test.JsonAssert.assertJson; | |||
import static org.sonarqube.ws.MediaTypes.PROTOBUF; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PERMISSION; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_TEMPLATE_ID; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_TEMPLATE_NAME; | |||
public class TemplateUsersActionTest { | |||
@Rule | |||
public ExpectedException expectedException = ExpectedException.none(); | |||
@Rule | |||
public UserSessionRule userSession = UserSessionRule.standalone(); | |||
@Rule | |||
public DbTester db = DbTester.create(System2.INSTANCE); | |||
ResourceTypesRule resourceTypes = new ResourceTypesRule().setRootQualifiers(Qualifiers.PROJECT, Qualifiers.VIEW, "DEV"); | |||
DbClient dbClient = db.getDbClient(); | |||
DbSession dbSession = db.getSession(); | |||
PermissionDependenciesFinder dependenciesFinder = new PermissionDependenciesFinder(dbClient, new ComponentFinder(dbClient), new UserGroupFinder(dbClient), resourceTypes); | |||
TemplateUsersAction underTest = new TemplateUsersAction(dbClient, userSession, dependenciesFinder); | |||
WsActionTester ws = new WsActionTester(underTest); | |||
@Test | |||
public void search_for_users_with_response_example() { | |||
setSysAdminUser(); | |||
UserDto user1 = insertUser(new UserDto().setLogin("admin").setName("Administrator").setEmail("admin@admin.com")); | |||
UserDto user2 = insertUser(new UserDto().setLogin("george.orwell").setName("George Orwell").setEmail("george.orwell@1984.net")); | |||
PermissionTemplateDto template1 = dbClient.permissionTemplateDao().insert(dbSession, newPermissionTemplateDto().setUuid("template-uuid-1")); | |||
addUserToTemplate(newPermissionTemplateUser(CODEVIEWER, template1.getId(), user1.getId())); | |||
addUserToTemplate(newPermissionTemplateUser(CODEVIEWER, template1.getId(), user2.getId())); | |||
addUserToTemplate(newPermissionTemplateUser(ADMIN, template1.getId(), user2.getId())); | |||
commit(); | |||
String result = newRequest(null, template1.getUuid()).execute().getInput(); | |||
assertJson(result).isSimilarTo(getClass().getResource("template_users-example.json")); | |||
} | |||
@Test | |||
public void search_for_users_by_template_name() throws IOException { | |||
setSysAdminUser(); | |||
UserDto user1 = insertUser(new UserDto().setLogin("login-1").setName("name-1").setEmail("email-1")); | |||
UserDto user2 = insertUser(new UserDto().setLogin("login-2").setName("name-2").setEmail("email-2")); | |||
UserDto user3 = insertUser(new UserDto().setLogin("login-3").setName("name-3").setEmail("email-3")); | |||
PermissionTemplateDto template = dbClient.permissionTemplateDao().insert(dbSession, newPermissionTemplateDto().setUuid("template-uuid-1")); | |||
addUserToTemplate(newPermissionTemplateUser(USER, template.getId(), user1.getId())); | |||
addUserToTemplate(newPermissionTemplateUser(USER, template.getId(), user2.getId())); | |||
addUserToTemplate(newPermissionTemplateUser(ISSUE_ADMIN, template.getId(), user1.getId())); | |||
addUserToTemplate(newPermissionTemplateUser(ISSUE_ADMIN, template.getId(), user3.getId())); | |||
PermissionTemplateDto anotherTemplate = dbClient.permissionTemplateDao().insert(dbSession, newPermissionTemplateDto().setUuid("template-uuid-2")); | |||
addUserToTemplate(newPermissionTemplateUser(USER, anotherTemplate.getId(), user1.getId())); | |||
commit(); | |||
InputStream responseStream = newRequest(null, null) | |||
.setParam(PARAM_TEMPLATE_NAME, template.getName()) | |||
.setMediaType(PROTOBUF) | |||
.execute().getInputStream(); | |||
WsPermissions.UsersWsResponse response = WsPermissions.UsersWsResponse.parseFrom(responseStream); | |||
assertThat(response.getUsersList()).extracting("login").containsExactly("login-1", "login-2", "login-3"); | |||
assertThat(response.getUsers(0).getPermissionsList()).containsOnly("issueadmin", "user"); | |||
assertThat(response.getUsers(1).getPermissionsList()).containsOnly("user"); | |||
assertThat(response.getUsers(2).getPermissionsList()).containsOnly("issueadmin"); | |||
} | |||
@Test | |||
public void search_using_text_query() throws IOException { | |||
setSysAdminUser(); | |||
UserDto user1 = insertUser(new UserDto().setLogin("login-1").setName("name-1").setEmail("email-1")); | |||
UserDto user2 = insertUser(new UserDto().setLogin("login-2").setName("name-2").setEmail("email-2")); | |||
UserDto user3 = insertUser(new UserDto().setLogin("login-3").setName("name-3").setEmail("email-3")); | |||
PermissionTemplateDto template = dbClient.permissionTemplateDao().insert(dbSession, newPermissionTemplateDto().setUuid("template-uuid-1")); | |||
addUserToTemplate(newPermissionTemplateUser(USER, template.getId(), user1.getId())); | |||
addUserToTemplate(newPermissionTemplateUser(USER, template.getId(), user2.getId())); | |||
addUserToTemplate(newPermissionTemplateUser(ISSUE_ADMIN, template.getId(), user1.getId())); | |||
addUserToTemplate(newPermissionTemplateUser(ISSUE_ADMIN, template.getId(), user3.getId())); | |||
PermissionTemplateDto anotherTemplate = dbClient.permissionTemplateDao().insert(dbSession, newPermissionTemplateDto().setUuid("template-uuid-2")); | |||
addUserToTemplate(newPermissionTemplateUser(USER, anotherTemplate.getId(), user1.getId())); | |||
commit(); | |||
InputStream responseStream = newRequest(null, null) | |||
.setParam(PARAM_TEMPLATE_NAME, template.getName()) | |||
.setParam(WebService.Param.TEXT_QUERY, "ame-1") | |||
.setMediaType(PROTOBUF) | |||
.execute().getInputStream(); | |||
WsPermissions.UsersWsResponse response = WsPermissions.UsersWsResponse.parseFrom(responseStream); | |||
assertThat(response.getUsersList()).extracting("login").containsOnly("login-1"); | |||
} | |||
@Test | |||
public void search_using_permission() throws IOException { | |||
setSysAdminUser(); | |||
UserDto user1 = insertUser(new UserDto().setLogin("login-1").setName("name-1").setEmail("email-1")); | |||
UserDto user2 = insertUser(new UserDto().setLogin("login-2").setName("name-2").setEmail("email-2")); | |||
UserDto user3 = insertUser(new UserDto().setLogin("login-3").setName("name-3").setEmail("email-3")); | |||
PermissionTemplateDto template = dbClient.permissionTemplateDao().insert(dbSession, newPermissionTemplateDto().setUuid("template-uuid-1")); | |||
addUserToTemplate(newPermissionTemplateUser(USER, template.getId(), user1.getId())); | |||
addUserToTemplate(newPermissionTemplateUser(USER, template.getId(), user2.getId())); | |||
addUserToTemplate(newPermissionTemplateUser(ISSUE_ADMIN, template.getId(), user1.getId())); | |||
addUserToTemplate(newPermissionTemplateUser(ISSUE_ADMIN, template.getId(), user3.getId())); | |||
PermissionTemplateDto anotherTemplate = dbClient.permissionTemplateDao().insert(dbSession, newPermissionTemplateDto().setUuid("template-uuid-2")); | |||
addUserToTemplate(newPermissionTemplateUser(USER, anotherTemplate.getId(), user1.getId())); | |||
commit(); | |||
InputStream responseStream = newRequest(USER, template.getUuid()) | |||
.setMediaType(PROTOBUF) | |||
.execute().getInputStream(); | |||
WsPermissions.UsersWsResponse response = WsPermissions.UsersWsResponse.parseFrom(responseStream); | |||
assertThat(response.getUsersList()).extracting("login").containsExactly("login-1", "login-2"); | |||
assertThat(response.getUsers(0).getPermissionsList()).containsOnly("issueadmin", "user"); | |||
assertThat(response.getUsers(1).getPermissionsList()).containsOnly("user"); | |||
} | |||
@Test | |||
public void search_with_pagination() throws IOException { | |||
setSysAdminUser(); | |||
UserDto user1 = insertUser(new UserDto().setLogin("login-1").setName("name-1").setEmail("email-1")); | |||
UserDto user2 = insertUser(new UserDto().setLogin("login-2").setName("name-2").setEmail("email-2")); | |||
UserDto user3 = insertUser(new UserDto().setLogin("login-3").setName("name-3").setEmail("email-3")); | |||
PermissionTemplateDto template = dbClient.permissionTemplateDao().insert(dbSession, newPermissionTemplateDto().setUuid("template-uuid-1")); | |||
addUserToTemplate(newPermissionTemplateUser(USER, template.getId(), user1.getId())); | |||
addUserToTemplate(newPermissionTemplateUser(USER, template.getId(), user2.getId())); | |||
addUserToTemplate(newPermissionTemplateUser(ISSUE_ADMIN, template.getId(), user1.getId())); | |||
addUserToTemplate(newPermissionTemplateUser(ISSUE_ADMIN, template.getId(), user3.getId())); | |||
PermissionTemplateDto anotherTemplate = dbClient.permissionTemplateDao().insert(dbSession, newPermissionTemplateDto().setUuid("template-uuid-2")); | |||
addUserToTemplate(newPermissionTemplateUser(USER, anotherTemplate.getId(), user1.getId())); | |||
commit(); | |||
InputStream responseStream = newRequest(USER, null) | |||
.setParam(PARAM_TEMPLATE_NAME, template.getName()) | |||
.setParam(WebService.Param.SELECTED, "all") | |||
.setParam(WebService.Param.PAGE, "2") | |||
.setParam(WebService.Param.PAGE_SIZE, "1") | |||
.setMediaType(PROTOBUF) | |||
.execute().getInputStream(); | |||
WsPermissions.UsersWsResponse response = WsPermissions.UsersWsResponse.parseFrom(responseStream); | |||
assertThat(response.getUsersList()).extracting("login").containsOnly("login-2"); | |||
} | |||
@Test | |||
public void users_are_sorted_by_name() throws IOException { | |||
setSysAdminUser(); | |||
UserDto user1 = insertUser(new UserDto().setLogin("login-2").setName("name-2")); | |||
UserDto user2 = insertUser(new UserDto().setLogin("login-3").setName("name-3")); | |||
UserDto user3 = insertUser(new UserDto().setLogin("login-1").setName("name-1")); | |||
PermissionTemplateDto template = dbClient.permissionTemplateDao().insert(dbSession, newPermissionTemplateDto().setUuid("template-uuid-1")); | |||
addUserToTemplate(newPermissionTemplateUser(USER, template.getId(), user1.getId())); | |||
addUserToTemplate(newPermissionTemplateUser(USER, template.getId(), user2.getId())); | |||
addUserToTemplate(newPermissionTemplateUser(ISSUE_ADMIN, template.getId(), user3.getId())); | |||
commit(); | |||
InputStream responseStream = newRequest(null, null) | |||
.setParam(PARAM_TEMPLATE_NAME, template.getName()) | |||
.setMediaType(PROTOBUF) | |||
.execute().getInputStream(); | |||
WsPermissions.UsersWsResponse response = WsPermissions.UsersWsResponse.parseFrom(responseStream); | |||
assertThat(response.getUsersList()).extracting("login").containsExactly("login-1", "login-2", "login-3"); | |||
} | |||
@Test | |||
public void empty_result_when_no_user_on_template() throws IOException { | |||
setSysAdminUser(); | |||
UserDto user = insertUser(new UserDto().setLogin("login-1").setName("name-1").setEmail("email-1")); | |||
PermissionTemplateDto template = dbClient.permissionTemplateDao().insert(dbSession, newPermissionTemplateDto().setUuid("template-uuid-1")); | |||
PermissionTemplateDto anotherTemplate = dbClient.permissionTemplateDao().insert(dbSession, newPermissionTemplateDto().setUuid("template-uuid-2")); | |||
addUserToTemplate(newPermissionTemplateUser(USER, anotherTemplate.getId(), user.getId())); | |||
commit(); | |||
InputStream responseStream = newRequest(null, null) | |||
.setParam(PARAM_TEMPLATE_NAME, template.getName()) | |||
.setMediaType(PROTOBUF) | |||
.execute().getInputStream(); | |||
WsPermissions.UsersWsResponse response = WsPermissions.UsersWsResponse.parseFrom(responseStream); | |||
assertThat(response.getUsersList()).isEmpty(); | |||
} | |||
@Test | |||
public void fail_if_not_a_project_permission() throws IOException { | |||
setSysAdminUser(); | |||
PermissionTemplateDto template = dbClient.permissionTemplateDao().insert(dbSession, newPermissionTemplateDto().setUuid("template-uuid-1")); | |||
commit(); | |||
expectedException.expect(BadRequestException.class); | |||
newRequest(GlobalPermissions.PROVISIONING, template.getUuid()) | |||
.execute(); | |||
} | |||
@Test | |||
public void fail_if_no_template_param() { | |||
setSysAdminUser(); | |||
expectedException.expect(BadRequestException.class); | |||
newRequest(null, null) | |||
.execute(); | |||
} | |||
@Test | |||
public void fail_if_template_does_not_exist() { | |||
setSysAdminUser(); | |||
expectedException.expect(NotFoundException.class); | |||
newRequest(null, "unknown-template-uuid") | |||
.execute(); | |||
} | |||
@Test | |||
public void fail_if_template_uuid_and_name_provided() { | |||
setSysAdminUser(); | |||
PermissionTemplateDto template = dbClient.permissionTemplateDao().insert(dbSession, newPermissionTemplateDto().setUuid("template-uuid-1")); | |||
commit(); | |||
expectedException.expect(BadRequestException.class); | |||
newRequest(null, template.getUuid()) | |||
.setParam(PARAM_TEMPLATE_NAME, template.getName()) | |||
.execute(); | |||
} | |||
@Test | |||
public void fail_if_not_logged_in() { | |||
userSession.anonymous(); | |||
PermissionTemplateDto template = dbClient.permissionTemplateDao().insert(dbSession, newPermissionTemplateDto().setUuid("template-uuid-1")); | |||
commit(); | |||
expectedException.expect(UnauthorizedException.class); | |||
newRequest(null, template.getUuid()).execute(); | |||
} | |||
@Test | |||
public void fail_if_insufficient_privileges() { | |||
userSession.login("login"); | |||
PermissionTemplateDto template = dbClient.permissionTemplateDao().insert(dbSession, newPermissionTemplateDto().setUuid("template-uuid-1")); | |||
commit(); | |||
expectedException.expect(ForbiddenException.class); | |||
newRequest(null, template.getUuid()).execute(); | |||
} | |||
private UserDto insertUser(UserDto userDto) { | |||
return dbClient.userDao().insert(dbSession, userDto.setActive(true)); | |||
} | |||
private void addUserToTemplate(PermissionTemplateUserDto dto) { | |||
dbClient.permissionTemplateDao().insertUserPermission(dbSession, dto.getTemplateId(), dto.getUserId(), dto.getPermission()); | |||
} | |||
private void commit() { | |||
dbSession.commit(); | |||
} | |||
private static PermissionTemplateUserDto newPermissionTemplateUser(String permission, long permissionTemplateId, long userId) { | |||
return newPermissionTemplateUserDto() | |||
.setPermission(permission) | |||
.setTemplateId(permissionTemplateId) | |||
.setUserId(userId); | |||
} | |||
private TestRequest newRequest(@Nullable String permission, @Nullable String templateUuid) { | |||
TestRequest request = ws.newRequest(); | |||
if (permission != null) { | |||
request.setParam(PARAM_PERMISSION, permission); | |||
} | |||
if (templateUuid != null) { | |||
request.setParam(PARAM_TEMPLATE_ID, templateUuid); | |||
} | |||
return request; | |||
} | |||
private void setSysAdminUser() { | |||
userSession.login("login").setGlobalPermissions(ADMIN); | |||
} | |||
} |
@@ -19,32 +19,16 @@ | |||
*/ | |||
package org.sonar.server.permission.ws; | |||
import org.junit.Before; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.ExpectedException; | |||
import org.sonar.api.resources.Qualifiers; | |||
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.api.web.UserRole; | |||
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.ResourceTypesRule; | |||
import org.sonar.db.permission.PermissionDbTester; | |||
import org.sonar.db.permission.UserPermissionDto; | |||
import org.sonar.db.user.UserDbTester; | |||
import org.sonar.db.user.UserDto; | |||
import org.sonar.server.component.ComponentFinder; | |||
import org.sonar.server.exceptions.BadRequestException; | |||
import org.sonar.server.exceptions.ForbiddenException; | |||
import org.sonar.server.exceptions.UnauthorizedException; | |||
import org.sonar.server.tester.UserSessionRule; | |||
import org.sonar.server.usergroups.ws.UserGroupFinder; | |||
import org.sonar.server.ws.WsActionTester; | |||
import org.sonar.server.ws.WsTester; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.sonar.api.server.ws.WebService.Param.TEXT_QUERY; | |||
@@ -56,86 +40,64 @@ import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN; | |||
import static org.sonar.db.component.ComponentTesting.newProjectDto; | |||
import static org.sonar.db.user.UserTesting.newUserDto; | |||
import static org.sonar.test.JsonAssert.assertJson; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.CONTROLLER; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PERMISSION; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PROJECT_ID; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PROJECT_KEY; | |||
public class UsersActionTest { | |||
public class UsersActionTest extends BasePermissionWsTest<UsersAction> { | |||
@Rule | |||
public ExpectedException expectedException = ExpectedException.none(); | |||
@Rule | |||
public UserSessionRule userSession = UserSessionRule.standalone(); | |||
@Rule | |||
public DbTester db = DbTester.create(System2.INSTANCE); | |||
DbClient dbClient = db.getDbClient(); | |||
DbSession dbSession = db.getSession(); | |||
UserDbTester userDb = new UserDbTester(db); | |||
PermissionDbTester permissionDb = new PermissionDbTester(db); | |||
ComponentDbTester componentDbTester = new ComponentDbTester(db); | |||
WsActionTester ws; | |||
ResourceTypesRule resourceTypes = new ResourceTypesRule().setRootQualifiers(Qualifiers.PROJECT, Qualifiers.VIEW, "DEV"); | |||
UsersAction underTest; | |||
@Before | |||
public void setUp() { | |||
PermissionDependenciesFinder dependenciesFinder = new PermissionDependenciesFinder(dbClient, new ComponentFinder(dbClient), new UserGroupFinder(dbClient), resourceTypes); | |||
underTest = new UsersAction(dbClient, userSession, dependenciesFinder); | |||
ws = new WsActionTester(underTest); | |||
userSession.login("login").setGlobalPermissions(SYSTEM_ADMIN); | |||
@Override | |||
protected UsersAction buildWsAction() { | |||
return new UsersAction(db.getDbClient(), userSession, newPermissionWsSupport()); | |||
} | |||
@Test | |||
public void search_for_users_with_response_example() { | |||
UserDto user2 = userDb.insertUser(new UserDto().setLogin("george.orwell").setName("George Orwell").setEmail("george.orwell@1984.net")); | |||
UserDto user1 = userDb.insertUser(new UserDto().setLogin("admin").setName("Administrator").setEmail("admin@admin.com")); | |||
permissionDb.addGlobalPermissionToUser(SCAN_EXECUTION, user2.getId()); | |||
permissionDb.addGlobalPermissionToUser(SYSTEM_ADMIN, user1.getId()); | |||
permissionDb.addGlobalPermissionToUser(QUALITY_GATE_ADMIN, user1.getId()); | |||
permissionDb.addGlobalPermissionToUser(QUALITY_PROFILE_ADMIN, user1.getId()); | |||
public void search_for_users_with_response_example() throws Exception { | |||
UserDto user1 = db.users().insertUser(newUserDto().setLogin("admin").setName("Administrator").setEmail("admin@admin.com")); | |||
UserDto user2 = db.users().insertUser(newUserDto().setLogin("george.orwell").setName("George Orwell").setEmail("george.orwell@1984.net")); | |||
db.users().insertPermissionOnUser(user1, SYSTEM_ADMIN); | |||
db.users().insertPermissionOnUser(user1, QUALITY_GATE_ADMIN); | |||
db.users().insertPermissionOnUser(user1, QUALITY_PROFILE_ADMIN); | |||
db.users().insertPermissionOnUser(user2, SCAN_EXECUTION); | |||
String result = ws.newRequest().execute().getInput(); | |||
loginAsAdmin(); | |||
String result = newRequest().execute().outputAsString(); | |||
assertJson(result).withStrictArrayOrder().isSimilarTo(getClass().getResource("users-example.json")); | |||
} | |||
@Test | |||
public void search_for_users_with_one_permission() { | |||
public void search_for_users_with_one_permission() throws Exception { | |||
insertUsersHavingGlobalPermissions(); | |||
String result = ws.newRequest().setParam("permission", "scan").execute().getInput(); | |||
loginAsAdmin(); | |||
String result = newRequest().setParam("permission", "scan").execute().outputAsString(); | |||
assertJson(result).withStrictArrayOrder().isSimilarTo(getClass().getResource("UsersActionTest/users.json")); | |||
} | |||
@Test | |||
public void search_for_users_with_permission_on_project() { | |||
userSession.login().addProjectUuidPermissions(SYSTEM_ADMIN, "project-uuid"); | |||
// User have permission on project | |||
ComponentDto project = componentDbTester.insertComponent(newProjectDto("project-uuid").setKey("project-key")); | |||
UserDto user = userDb.insertUser(newUserDto()); | |||
insertUserPermission(new UserPermissionDto(ISSUE_ADMIN, user.getId(), project.getId())); | |||
public void search_for_users_with_permission_on_project() throws Exception { | |||
// User has permission on project | |||
ComponentDto project = db.components().insertComponent(newProjectDto()); | |||
UserDto user = db.users().insertUser(newUserDto()); | |||
db.users().insertProjectPermissionOnUser(user, ISSUE_ADMIN, project); | |||
// User have permission on another project | |||
ComponentDto anotherProject = componentDbTester.insertComponent(newProjectDto()); | |||
UserDto userHavePermissionOnAnotherProject = userDb.insertUser(newUserDto()); | |||
insertUserPermission(new UserPermissionDto(ISSUE_ADMIN, userHavePermissionOnAnotherProject.getId(), anotherProject.getId())); | |||
// User has permission on another project | |||
ComponentDto anotherProject = db.components().insertComponent(newProjectDto()); | |||
UserDto userHavePermissionOnAnotherProject = db.users().insertUser(newUserDto()); | |||
db.users().insertProjectPermissionOnUser(userHavePermissionOnAnotherProject, ISSUE_ADMIN, anotherProject); | |||
// User has no permission | |||
UserDto withoutPermission = userDb.insertUser(newUserDto()); | |||
dbSession.commit(); | |||
UserDto withoutPermission = db.users().insertUser(newUserDto()); | |||
String result = ws.newRequest() | |||
userSession.login().addProjectUuidPermissions(SYSTEM_ADMIN, project.uuid()); | |||
String result = newRequest() | |||
.setParam(PARAM_PERMISSION, ISSUE_ADMIN) | |||
.setParam(PARAM_PROJECT_ID, "project-uuid") | |||
.execute().getInput(); | |||
.setParam(PARAM_PROJECT_ID, project.uuid()) | |||
.execute() | |||
.outputAsString(); | |||
assertThat(result).contains(user.getLogin()) | |||
.doesNotContain(userHavePermissionOnAnotherProject.getLogin()) | |||
@@ -143,46 +105,42 @@ public class UsersActionTest { | |||
} | |||
@Test | |||
public void search_only_for_users_with_permission_when_no_search_query() { | |||
userSession.login().setGlobalPermissions(SYSTEM_ADMIN); | |||
public void search_only_for_users_with_permission_when_no_search_query() throws Exception { | |||
// User have permission on project | |||
ComponentDto project = componentDbTester.insertComponent(newProjectDto()); | |||
UserDto user = userDb.insertUser(newUserDto()); | |||
insertUserPermission(new UserPermissionDto(ISSUE_ADMIN, user.getId(), project.getId())); | |||
ComponentDto project = db.components().insertComponent(newProjectDto()); | |||
UserDto user = db.users().insertUser(newUserDto()); | |||
db.users().insertProjectPermissionOnUser(user, ISSUE_ADMIN, project); | |||
// User has no permission | |||
UserDto withoutPermission = userDb.insertUser(newUserDto()); | |||
dbSession.commit(); | |||
UserDto withoutPermission = db.users().insertUser(newUserDto()); | |||
String result = ws.newRequest() | |||
loginAsAdmin(); | |||
String result = newRequest() | |||
.setParam(PARAM_PROJECT_ID, project.uuid()) | |||
.execute().getInput(); | |||
.execute() | |||
.outputAsString(); | |||
assertThat(result).contains(user.getLogin()) | |||
.doesNotContain(withoutPermission.getLogin()); | |||
} | |||
@Test | |||
public void search_also_for_users_without_permission_when_search_query() { | |||
userSession.login().setGlobalPermissions(SYSTEM_ADMIN); | |||
public void search_also_for_users_without_permission_when_search_query() throws Exception { | |||
// User with permission on project | |||
ComponentDto project = componentDbTester.insertComponent(newProjectDto()); | |||
UserDto user = userDb.insertUser(newUserDto("with-permission", "with-permission", null)); | |||
insertUserPermission(new UserPermissionDto(ISSUE_ADMIN, user.getId(), project.getId())); | |||
ComponentDto project = db.components().insertComponent(newProjectDto()); | |||
UserDto user = db.users().insertUser(newUserDto("with-permission", "with-permission", null)); | |||
db.users().insertProjectPermissionOnUser(user, ISSUE_ADMIN, project); | |||
// User without permission | |||
UserDto withoutPermission = userDb.insertUser(newUserDto("without-permission", "without-permission", null)); | |||
UserDto anotherUser = userDb.insertUser(newUserDto("another-user", "another-user", null)); | |||
dbSession.commit(); | |||
UserDto withoutPermission = db.users().insertUser(newUserDto("without-permission", "without-permission", null)); | |||
UserDto anotherUser = db.users().insertUser(newUserDto("another-user", "another-user", null)); | |||
String result = ws.newRequest() | |||
loginAsAdmin(); | |||
String result = newRequest() | |||
.setParam(PARAM_PROJECT_ID, project.uuid()) | |||
.setParam(TEXT_QUERY, "with") | |||
.execute().getInput(); | |||
.execute() | |||
.outputAsString(); | |||
assertThat(result).contains(user.getLogin()) | |||
.contains(withoutPermission.getLogin()) | |||
@@ -190,12 +148,15 @@ public class UsersActionTest { | |||
} | |||
@Test | |||
public void search_for_users_with_query_as_a_parameter() { | |||
public void search_for_users_with_query_as_a_parameter() throws Exception { | |||
insertUsersHavingGlobalPermissions(); | |||
String result = ws.newRequest() | |||
loginAsAdmin(); | |||
String result = newRequest() | |||
.setParam("permission", "scan") | |||
.setParam(TEXT_QUERY, "ame-1") | |||
.execute().getInput(); | |||
.execute() | |||
.outputAsString(); | |||
assertThat(result).contains("login-1") | |||
.doesNotContain("login-2") | |||
@@ -203,52 +164,60 @@ public class UsersActionTest { | |||
} | |||
@Test | |||
public void search_for_users_with_select_as_a_parameter() { | |||
public void search_for_users_with_select_as_a_parameter() throws Exception { | |||
insertUsersHavingGlobalPermissions(); | |||
String result = ws.newRequest() | |||
.execute().getInput(); | |||
loginAsAdmin(); | |||
String result = newRequest() | |||
.execute() | |||
.outputAsString(); | |||
assertThat(result).contains("login-1", "login-2", "login-3"); | |||
} | |||
@Test | |||
public void fail_if_project_permission_without_project() { | |||
public void fail_if_project_permission_without_project() throws Exception { | |||
loginAsAdmin(); | |||
expectedException.expect(BadRequestException.class); | |||
ws.newRequest() | |||
newRequest() | |||
.setParam(PARAM_PERMISSION, UserRole.ISSUE_ADMIN) | |||
.setParam(Param.SELECTED, SelectionMode.ALL.value()) | |||
.execute(); | |||
} | |||
@Test | |||
public void fail_if_insufficient_privileges() { | |||
expectedException.expect(ForbiddenException.class); | |||
public void fail_if_insufficient_privileges() throws Exception { | |||
userSession.login("login"); | |||
ws.newRequest() | |||
expectedException.expect(ForbiddenException.class); | |||
newRequest() | |||
.setParam("permission", SYSTEM_ADMIN) | |||
.execute(); | |||
} | |||
@Test | |||
public void fail_if_not_logged_in() { | |||
expectedException.expect(UnauthorizedException.class); | |||
public void fail_if_not_logged_in() throws Exception { | |||
userSession.anonymous(); | |||
ws.newRequest() | |||
expectedException.expect(UnauthorizedException.class); | |||
newRequest() | |||
.setParam("permission", SYSTEM_ADMIN) | |||
.execute(); | |||
} | |||
@Test | |||
public void fail_if_project_uuid_and_project_key_are_provided() { | |||
public void fail_if_project_uuid_and_project_key_are_provided() throws Exception { | |||
db.components().insertComponent(newProjectDto("project-uuid").setKey("project-key")); | |||
loginAsAdmin(); | |||
expectedException.expect(BadRequestException.class); | |||
expectedException.expectMessage("Project id or project key can be provided, not both."); | |||
dbClient.componentDao().insert(dbSession, newProjectDto("project-uuid").setKey("project-key")); | |||
dbSession.commit(); | |||
ws.newRequest() | |||
newRequest() | |||
.setParam(PARAM_PERMISSION, SYSTEM_ADMIN) | |||
.setParam(PARAM_PROJECT_ID, "project-uuid") | |||
.setParam(PARAM_PROJECT_KEY, "project-key") | |||
@@ -256,31 +225,29 @@ public class UsersActionTest { | |||
} | |||
@Test | |||
public void fail_if_search_query_is_too_short() { | |||
public void fail_if_search_query_is_too_short() throws Exception { | |||
loginAsAdmin(); | |||
expectedException.expect(BadRequestException.class); | |||
expectedException.expectMessage("The 'q' parameter must have at least 3 characters"); | |||
ws.newRequest().setParam(TEXT_QUERY, "ab").execute(); | |||
newRequest().setParam(TEXT_QUERY, "ab").execute(); | |||
} | |||
private UserDto insertUser(UserDto userDto) { | |||
UserDto user = dbClient.userDao().insert(dbSession, userDto.setActive(true)); | |||
dbSession.commit(); | |||
return user; | |||
private void insertUsersHavingGlobalPermissions() { | |||
UserDto user1 = db.users().insertUser(newUserDto("login-1", "name-1", "email-1")); | |||
UserDto user2 = db.users().insertUser(newUserDto("login-2", "name-2", "email-2")); | |||
UserDto user3 = db.users().insertUser(newUserDto("login-3", "name-3", "email-3")); | |||
db.users().insertPermissionOnUser(user1, SCAN_EXECUTION); | |||
db.users().insertPermissionOnUser(user2, SCAN_EXECUTION); | |||
db.users().insertPermissionOnUser(user3, SYSTEM_ADMIN); | |||
} | |||
private void insertUserPermission(UserPermissionDto userPermissionDto) { | |||
dbClient.userPermissionDao().insert(dbSession, userPermissionDto); | |||
dbSession.commit(); | |||
private WsTester.TestRequest newRequest() { | |||
return wsTester.newPostRequest(CONTROLLER, "users"); | |||
} | |||
private void insertUsersHavingGlobalPermissions() { | |||
UserDto user3 = insertUser(new UserDto().setLogin("login-3").setName("name-3").setEmail("email-3")); | |||
UserDto user2 = insertUser(new UserDto().setLogin("login-2").setName("name-2").setEmail("email-2")); | |||
UserDto user1 = insertUser(new UserDto().setLogin("login-1").setName("name-1").setEmail("email-1")); | |||
insertUserPermission(new UserPermissionDto(SCAN_EXECUTION, user1.getId(), null)); | |||
insertUserPermission(new UserPermissionDto(SYSTEM_ADMIN, user3.getId(), null)); | |||
insertUserPermission(new UserPermissionDto(SCAN_EXECUTION, user2.getId(), null)); | |||
dbSession.commit(); | |||
private void loginAsAdmin() { | |||
userSession.login("login").setGlobalPermissions(SYSTEM_ADMIN); | |||
} | |||
} |
@@ -57,6 +57,7 @@ public class WsTester { | |||
private final String method; | |||
private String path; | |||
private String mediaType = MediaTypes.JSON; | |||
private Map<String, String> params = Maps.newHashMap(); | |||
private final Map<String, Part> parts = Maps.newHashMap(); | |||
@@ -72,7 +73,12 @@ public class WsTester { | |||
@Override | |||
public String getMediaType() { | |||
return MediaTypes.JSON; | |||
return mediaType; | |||
} | |||
public TestRequest setMediaType(String s) { | |||
this.mediaType = s; | |||
return this; | |||
} | |||
@Override |
@@ -27,6 +27,7 @@ import static java.util.Objects.requireNonNull; | |||
public class AddGroupWsRequest { | |||
private String permission; | |||
private String groupId; | |||
private String organizationKey; | |||
private String groupName; | |||
private String projectId; | |||
private String projectKey; | |||
@@ -50,6 +51,16 @@ public class AddGroupWsRequest { | |||
return this; | |||
} | |||
@CheckForNull | |||
public String getOrganizationKey() { | |||
return organizationKey; | |||
} | |||
public AddGroupWsRequest setOrganizationKey(@Nullable String s) { | |||
this.organizationKey = s; | |||
return this; | |||
} | |||
@CheckForNull | |||
public String getGroupName() { | |||
return groupName; |
@@ -23,6 +23,7 @@ public class PermissionsWsParameters { | |||
public static final String CONTROLLER = "api/permissions"; | |||
public static final String PARAM_PERMISSION = "permission"; | |||
public static final String PARAM_ORGANIZATION_KEY = "organization"; | |||
public static final String PARAM_GROUP_NAME = "groupName"; | |||
public static final String PARAM_GROUP_ID = "groupId"; | |||
public static final String PARAM_PROJECT_ID = "projectId"; |