import com.google.common.base.Strings;
import com.google.common.io.Resources;
import java.util.Date;
+import java.util.Optional;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.apache.commons.lang.BooleanUtils;
import org.sonar.core.util.Uuids;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
+import org.sonar.db.component.ComponentDto;
+import org.sonar.db.issue.IssueDto;
+import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.user.UserDto;
import org.sonar.server.issue.IssueFieldsSetter;
import org.sonar.server.issue.IssueFinder;
import org.sonar.server.user.UserSession;
import static com.google.common.base.Strings.emptyToNull;
+import static java.lang.String.format;
+import static java.util.Objects.requireNonNull;
import static org.sonar.server.ws.WsUtils.checkFound;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.ACTION_ASSIGN;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_ASSIGNEE;
private void assign(String issueKey, @Nullable String assignee) {
try (DbSession dbSession = dbClient.openSession(false)) {
- DefaultIssue issue = issueFinder.getByKey(dbSession, issueKey).toDefaultIssue();
+ IssueDto issueDto = issueFinder.getByKey(dbSession, issueKey);
+ DefaultIssue issue = issueDto.toDefaultIssue();
UserDto user = getUser(dbSession, assignee);
+ if (user != null) {
+ checkMembership(dbSession, issueDto, user);
+ }
IssueChangeContext context = IssueChangeContext.createUser(new Date(system2.now()), userSession.getLogin());
if (issueFieldsSetter.assign(issue, user, context)) {
issueUpdater.saveIssue(dbSession, issue, context, null);
if (Strings.isNullOrEmpty(assignee)) {
return null;
}
- UserDto user = dbClient.userDao().selectByLogin(dbSession, assignee);
- return checkFound(user != null && user.isActive() ? user : null, "Unknown user: %s", assignee);
+ return checkFound(dbClient.userDao().selectActiveUserByLogin(dbSession, assignee), "Unknown user: %s", assignee);
+ }
+
+ private void checkMembership(DbSession dbSession, IssueDto issueDto, UserDto user) {
+ String projectUuid = requireNonNull(issueDto.getProjectUuid());
+ ComponentDto project = Optional.ofNullable(dbClient.componentDao().selectByUuid(dbSession, projectUuid).orNull())
+ .orElseThrow(() -> new IllegalStateException(format("Unknown project %s", projectUuid)));
+ OrganizationDto organizationDto = dbClient.organizationDao().selectByUuid(dbSession, project.getOrganizationUuid())
+ .orElseThrow(() -> new IllegalStateException(format("Unknown organization %s", project.getOrganizationUuid())));
+ dbClient.organizationMemberDao().select(dbSession, organizationDto.getUuid(), user.getId())
+ .orElseThrow(() -> new IllegalArgumentException(format("User '%s' is not member of organization '%s'", user.getLogin(), organizationDto.getKey())));
}
}
package org.sonar.server.issue.ws;
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.internal.TestSystem2;
import org.sonar.db.DbTester;
import org.sonar.db.issue.IssueDto;
+import org.sonar.db.organization.OrganizationDto;
+import org.sonar.db.user.UserDto;
import org.sonar.server.es.EsTester;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.NotFoundException;
new IssueUpdater(db.getDbClient(),
new ServerIssueStorage(system2, new DefaultRuleFinder(db.getDbClient()), db.getDbClient(), issueIndexer), mock(NotificationManager.class)),
responseWriter);
- private WsActionTester tester = new WsActionTester(underTest);
-
- @Before
- public void setUp() throws Exception {
- db.users().insertUser(PREVIOUS_ASSIGNEE);
- }
+ private WsActionTester ws = new WsActionTester(underTest);
@Test
public void assign_to_someone() throws Exception {
IssueDto issue = newIssueWithBrowsePermission();
- db.users().insertUser("arthur");
+ UserDto userDto = db.users().insertUser("arthur");
+ addUserAsMemberOfDefaultOrganization(userDto);
- tester.newRequest()
+ ws.newRequest()
.setParam("issue", issue.getKey())
.setParam("assignee", "arthur")
.execute();
public void assign_to_me() throws Exception {
IssueDto issue = newIssueWithBrowsePermission();
- tester.newRequest()
+ ws.newRequest()
.setParam("issue", issue.getKey())
.setParam("assignee", "_me")
.execute();
public void assign_to_me_using_deprecated_me_param() throws Exception {
IssueDto issue = newIssueWithBrowsePermission();
- tester.newRequest()
+ ws.newRequest()
.setParam("issue", issue.getKey())
.setParam("me", "true")
.execute();
public void unassign() throws Exception {
IssueDto issue = newIssueWithBrowsePermission();
- tester.newRequest()
+ ws.newRequest()
.setParam("issue", issue.getKey())
.execute();
public void unassign_with_empty_assignee_param() throws Exception {
IssueDto issue = newIssueWithBrowsePermission();
- tester.newRequest()
+ ws.newRequest()
.setParam("issue", issue.getKey())
.setParam("assignee", "")
.execute();
@Test
public void nothing_to_do_when_new_assignee_is_same_as_old_one() throws Exception {
- db.users().insertUser("arthur");
IssueDto issue = newIssueWithBrowsePermission();
+ UserDto userDto = db.users().insertUser(PREVIOUS_ASSIGNEE);
+ addUserAsMemberOfDefaultOrganization(userDto);
- tester.newRequest()
+ ws.newRequest()
.setParam("issue", issue.getKey())
.setParam("assignee", PREVIOUS_ASSIGNEE)
.execute();
expectedException.expect(NotFoundException.class);
- tester.newRequest()
+ ws.newRequest()
.setParam("issue", issue.getKey())
.setParam("assignee", "unknown")
.execute();
expectedException.expect(NotFoundException.class);
- tester.newRequest()
+ ws.newRequest()
.setParam("issue", issue.getKey())
.setParam("assignee", "unknown")
.execute();
expectedException.expect(UnauthorizedException.class);
- tester.newRequest()
+ ws.newRequest()
.setParam("issue", issue.getKey())
.setParam("assignee", "_me")
.execute();
@Test
public void fail_when_missing_browse_permission() throws Exception {
IssueDto issue = newIssue();
- db.users().insertUser(CURRENT_USER_LOGIN);
userSession.logIn(CURRENT_USER_LOGIN).addProjectUuidPermissions(CODEVIEWER, issue.getProjectUuid());
expectedException.expect(ForbiddenException.class);
- tester.newRequest()
+ ws.newRequest()
.setParam("issue", issue.getKey())
.setParam("assignee", "_me")
.execute();
}
+ @Test
+ public void fail_when_assignee_is_not_member_of_organization_of_project_issue() throws Exception {
+ OrganizationDto org = db.organizations().insert(organizationDto -> organizationDto.setKey("Organization key"));
+ IssueDto issueDto = db.issues().insertIssue(org);
+ setUserWithBrowsePermission(issueDto);
+ OrganizationDto otherOrganization = db.organizations().insert();
+ UserDto assignee = db.users().insertUser("arthur");
+ db.organizations().addMember(otherOrganization, assignee);
+
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("User 'arthur' is not member of organization 'Organization key'");
+
+ ws.newRequest()
+ .setParam("issue", issueDto.getKey())
+ .setParam("assignee", "arthur")
+ .execute();
+ }
+
private IssueDto newIssue() {
return db.issues().insertIssue(
issueDto -> issueDto
.setUpdatedAt(PAST).setIssueUpdateTime(PAST));
}
- private void setUserWithBrowsePermission(IssueDto issue) {
- db.users().insertUser(CURRENT_USER_LOGIN);
- userSession.logIn(CURRENT_USER_LOGIN).addProjectUuidPermissions(USER, issue.getProjectUuid());
- }
-
private IssueDto newIssueWithBrowsePermission() {
IssueDto issue = newIssue();
setUserWithBrowsePermission(issue);
return issue;
}
+ private void setUserWithBrowsePermission(IssueDto issue) {
+ UserDto currentUser = db.users().insertUser(CURRENT_USER_LOGIN);
+ addUserAsMemberOfDefaultOrganization(currentUser);
+ userSession.logIn(CURRENT_USER_LOGIN).addProjectUuidPermissions(USER, issue.getProjectUuid());
+ }
+
private void checkIssueAssignee(String issueKey, @Nullable String expectedAssignee) {
IssueDto issueReloaded = db.getDbClient().issueDao().selectByKey(db.getSession(), issueKey).get();
assertThat(issueReloaded.getAssignee()).isEqualTo(expectedAssignee);
assertThat(issueReloaded.getIssueUpdateTime()).isEqualTo(NOW);
assertThat(issueReloaded.getUpdatedAt()).isEqualTo(NOW);
}
+
+ private void addUserAsMemberOfDefaultOrganization(UserDto user) {
+ db.organizations().addMember(db.getDefaultOrganization(), user);
+ }
+
}