import org.sonar.server.issue.IssueUpdater;
import org.sonar.server.issue.TransitionService;
import org.sonar.server.user.UserSession;
-
+import static org.sonar.server.ws.WsUtils.checkRequest;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.ACTION_DO_TRANSITION;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_ISSUE;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_TRANSITION;
String issue = request.mandatoryParam(PARAM_ISSUE);
try (DbSession dbSession = dbClient.openSession(false)) {
IssueDto issueDto = issueFinder.getByKey(dbSession, issue);
+ checkRequest(!issueDto.isExternal(), "Transition are not allowed on issues imported from external rule engines");
SearchResponseData preloadedSearchResponseData = doTransition(dbSession, issueDto, request.mandatoryParam(PARAM_TRANSITION));
responseWriter.write(issue, preloadedSearchResponseData, request, response);
}
import org.sonar.server.user.UserSession;
import org.sonarqube.ws.Issues.SearchWsResponse;
+import static com.google.common.base.MoreObjects.firstNonNull;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.collect.Iterables.concat;
import static com.google.common.collect.Sets.newHashSet;
// Must be done after loading of data as the "hidden" facet "debt"
// can be used to get total debt.
facets = reorderFacets(facets, options.getFacets());
- replaceRuleIdsByRuleKeys(facets, data.getRules() == null ? emptyList() : data.getRules());
+ replaceRuleIdsByRuleKeys(facets, firstNonNull(data.getRules(), emptyList()));
// FIXME allow long in Paging
Paging paging = forPageIndex(options.getPage()).withPageSize(options.getLimit()).andTotal((int) result.getHits().getTotalHits());
import org.sonarqube.ws.Issues.Transitions;
import org.sonarqube.ws.Issues.Users;
+import static com.google.common.base.MoreObjects.firstNonNull;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.base.Strings.emptyToNull;
import static com.google.common.base.Strings.nullToEmpty;
+import static java.util.Collections.emptyList;
import static org.sonar.api.rule.RuleKey.EXTERNAL_RULE_REPO_PREFIX;
import static org.sonar.core.util.Protobuf.setNullable;
private Common.Rules.Builder formatRules(SearchResponseData data) {
Common.Rules.Builder wsRules = Common.Rules.newBuilder();
- List<RuleDefinitionDto> rules = data.getRules();
- if (rules != null) {
- for (RuleDefinitionDto rule : rules) {
- wsRules.addRules(commonFormat.formatRule(rule));
- }
+ List<RuleDefinitionDto> rules = firstNonNull(data.getRules(), emptyList());
+ for (RuleDefinitionDto rule : rules) {
+ wsRules.addRules(commonFormat.formatRule(rule));
}
return wsRules;
}
.stream()
.filter(ComponentDto::isRootProject)
.collect(MoreCollectors.uniqueIndex(ComponentDto::projectUuid));
- for (IssueDto dto : result.getIssues()) {
+ for (IssueDto issueDto : result.getIssues()) {
// so that IssueDto can be used.
if (collector.contains(ACTIONS)) {
- ComponentDto project = componentsByProjectUuid.get(dto.getProjectUuid());
- result.addActions(dto.getKey(), listAvailableActions(dto, project));
+ ComponentDto project = componentsByProjectUuid.get(issueDto.getProjectUuid());
+ result.addActions(issueDto.getKey(), listAvailableActions(issueDto, project));
}
- if (collector.contains(TRANSITIONS)) {
+ if (collector.contains(TRANSITIONS) && !issueDto.isExternal()) {
// TODO workflow and action engines must not depend on org.sonar.api.issue.Issue but on a generic interface
- DefaultIssue issue = dto.toDefaultIssue();
+ DefaultIssue issue = issueDto.toDefaultIssue();
result.addTransitions(issue.key(), transitionService.listTransitions(issue));
}
}
import org.sonar.db.rule.RuleDefinitionDto;
import org.sonar.db.rule.RuleDto;
import org.sonar.server.es.EsTester;
+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 static org.sonar.api.web.UserRole.USER;
import static org.sonar.db.component.ComponentTesting.newFileDto;
import static org.sonar.db.issue.IssueTesting.newDto;
+import static org.sonar.db.rule.RuleTesting.newRule;
import static org.sonar.db.rule.RuleTesting.newRuleDto;
public class DoTransitionActionTest {
call("ISSUE_KEY", "confirm");
}
+ @Test
+ public void fail_if_external_issue() {
+ expectedException.expect(BadRequestException.class);
+
+ RuleDefinitionDto rule = ruleDbTester.insert(newRule()
+ .setIsExternal(true));
+ IssueDto issueDto = issueDbTester.insertIssue(newIssue()
+ .setStatus(STATUS_OPEN)
+ .setResolution(null)
+ .setRuleId(rule.getId())
+ .setRuleKey(rule.getRuleKey(), rule.getRepositoryKey()));
+ userSession.logIn("john").addProjectPermission(USER, project, file);
+
+ call(issueDto.getKey(), "confirm");
+ }
+
private TestResponse call(@Nullable String issueKey, @Nullable String transition) {
TestRequest request = tester.newRequest();
if (issueKey != null) {
ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization2, "PROJECT_ID").setDbKey("PROJECT_KEY"));
indexPermissions();
ComponentDto file = insertComponent(newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY"));
- IssueDto issue = IssueTesting.newDto(newRule(), file, project)
+ IssueDto issue = IssueTesting.newDto(newExternalRule(), file, project)
.setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2")
.setEffort(10L)
.setLine(42)