![JAR search and dependency download from the Maven repository](/logo.png)
me.shib.lib.jirabugsbuddy.VulnerabilityIssueHandler Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jira-bugs-buddy Show documentation
Show all versions of jira-bugs-buddy Show documentation
A plug that helps in building automation to create and maintain bugs in JIRA
package me.shib.lib.jirabugsbuddy;
import me.shib.lib.jirabugsbuddy.types.JiraConfig;
import me.shib.lib.jirabugsbuddy.types.Vulnerability;
import net.rcarz.jiraclient.*;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
public class VulnerabilityIssueHandler {
private JiraConfig jiraConfig;
private String repo;
private JiraClient jira;
private String project;
public VulnerabilityIssueHandler(String repo) throws IOException, JiraException {
this.jiraConfig = JiraConfig.getConfig();
this.jira = JiraConfig.getJiraClient();
this.project = jiraConfig.getProjectKey();
this.repo = repo;
}
private void createIssueForVulnerability(Vulnerability vulnerability) throws JiraException {
String summary = vulnerability.getJiraSummary(repo);
Issue.FluentCreate fluentCreate = jira.createIssue(project, jiraConfig.getIssueType())
.field(Field.SUMMARY, summary)
.field(Field.DESCRIPTION, vulnerability.getJiraDescription(repo))
.field(Field.LABELS, vulnerability.getJiraLabels(repo, jiraConfig.getAutomationLabel()))
.field(Field.PRIORITY, vulnerability.getPriority());
if (jiraConfig.getUsers().getReporter() != null) {
fluentCreate.field(Field.REPORTER, jiraConfig.getUsers().getReporter());
}
if (jiraConfig.getUsers().getAssignee() != null) {
fluentCreate.field(Field.ASSIGNEE, jiraConfig.getUsers().getAssignee());
}
for (String key : jiraConfig.getCustomFields().keySet()) {
fluentCreate.field(key, Field.valueById(jiraConfig.getCustomFields().get(key)));
}
Issue issue = fluentCreate.execute();
for (String watcher : jiraConfig.getUsers().getWatchers()) {
issue.addWatcher(watcher);
}
System.out.println("Created new issue: " + summary + " with priority "
+ vulnerability.getPriority());
}
private void updateIssueForVulnerability(Issue issue, Vulnerability vulnerability) throws JiraException {
boolean issueUpdated = false;
Issue.FluentUpdate fluentUpdate = issue.update();
if (jiraConfig.isSummaryUpdateAllowed() && !issue.getSummary().contentEquals(vulnerability.getJiraSummary(repo))) {
fluentUpdate.field(Field.SUMMARY, vulnerability.getJiraSummary(repo));
issueUpdated = true;
}
if (jiraConfig.isSummaryUpdateAllowed() && !issue.getDescription().contentEquals(vulnerability.getJiraDescription(repo))) {
fluentUpdate.field(Field.DESCRIPTION, vulnerability.getJiraDescription(repo));
issueUpdated = true;
}
StringBuilder comment = new StringBuilder();
int issuePriority;
try {
issuePriority = jiraConfig.getPriorities().get(issue.getPriority().getName());
} catch (Exception e) {
issuePriority = -1;
}
int vulnerabilityPriority = jiraConfig.getPriorities().get(vulnerability.getPriority());
if (issuePriority < vulnerabilityPriority) {
fluentUpdate.field(Field.PRIORITY, vulnerability.getPriority());
comment.append("Reprioritizing to *")
.append(vulnerability.getPriority())
.append("* based on actual priority.");
issueUpdated = true;
}
if (issueUpdated) {
fluentUpdate.execute();
if (!comment.toString().isEmpty()) {
issue.addComment(comment.toString());
}
}
if (jiraConfig.isOpenAllowed(issue.getStatus().getName())) {
openIssue(issue);
} else if (issueUpdated) {
System.out.println("Updated the issue: " + issue.getKey() + " - "
+ issue.getSummary());
} else {
System.out.println("Issue up-to date: " + issue.getKey() + " - "
+ issue.getSummary());
}
}
private void processVulnerability(Vulnerability vulnerability) throws Exception {
StringBuilder jql = new StringBuilder();
jql.append("project = ").append(project);
jql.append(" AND issuetype = \"").append(jiraConfig.getIssueType()).append("\"");
for (String label : vulnerability.getJiraLabels(repo, jiraConfig.getAutomationLabel())) {
jql.append(" AND labels = ").append("\"").append(label).append("\"");
}
List issues = jira.searchIssues(jql.toString(), JiraConfig.maxSearchResult).issues;
if (issues.size() == 0) {
createIssueForVulnerability(vulnerability);
} else {
if (issues.size() == 1) {
updateIssueForVulnerability(issues.get(0), vulnerability);
} else {
throw new Exception("More than one issue listed:\n"
+ "Labels: " + Arrays.toString(vulnerability.getJiraLabels(repo, jiraConfig.getAutomationLabel()).toArray()) + "\n"
+ "Issues: " + Arrays.toString(issues.toArray()));
}
}
}
private boolean isVulnerabilityExists(Issue issue, List vulnerabilities) {
for (Vulnerability vulnerability : vulnerabilities) {
if (issue.getLabels().containsAll(vulnerability.getJiraKeyLabels())) {
return true;
}
}
return false;
}
private String getStatusTransition(Issue issue, String status) throws JiraException {
List transitions = issue.getTransitions();
for (Transition transition : transitions) {
if (transition.getToStatus().getName().equalsIgnoreCase(status)) {
return transition.getName();
}
}
return null;
}
private boolean transitionIssue(List transitions, Issue issue, String verb) throws JiraException {
if (transitions.size() > 1) {
StringBuilder consoleLog = new StringBuilder();
consoleLog.append(" ").append(verb).append(" the issue ")
.append(issue.getKey()).append(": ").append(transitions.get(0));
for (int i = 1; i < transitions.size(); i++) {
consoleLog.append(" -> ").append(transitions.get(i));
issue.transition().execute(getStatusTransition(issue, transitions.get(i)));
}
System.out.print(consoleLog.toString());
return true;
}
return false;
}
private void openIssue(Issue issue) throws JiraException {
System.out.print("Issue: " + issue.getKey() + " is closed, but not actually fixed. ");
boolean transitioned = false;
if (jiraConfig.toOpen().isTansitionAllowed()) {
List transitions = jiraConfig.getTransitionsToOpen(issue.getStatus().getName());
transitioned = transitionIssue(transitions, issue, "Reopening");
if (!transitioned) {
System.out.println(" No path defined to Open the issue from \"" + issue.getStatus().getName() + "\" state.");
}
}
if (jiraConfig.toOpen().isCommentingAllowed(issue, JiraConfig.issueNotFixedComment)) {
StringBuilder comment = new StringBuilder();
comment.append(JiraConfig.issueNotFixedComment);
if (!transitioned) {
comment.append(JiraConfig.issueReopenComment);
}
if (!jira.getSelf().equalsIgnoreCase(issue.getAssignee().getName())) {
comment.append(" [~").append(issue.getAssignee().getName()).append("]");
}
issue.addComment(comment.toString());
}
System.out.print("\n");
}
private void closeIssue(Issue issue) throws JiraException {
System.out.print("Issue: " + issue.getKey() + " has been fixed.");
boolean transitioned = false;
if (jiraConfig.toClose().isTansitionAllowed()) {
List transitions = jiraConfig.getTransitionsToClose(issue.getStatus().getName());
transitioned = transitionIssue(transitions, issue, "Closing");
if (!transitioned) {
System.out.println(" No path defined to Close the issue from \"" + issue.getStatus().getName() + "\" state.");
}
}
if (jiraConfig.toClose().isCommentingAllowed(issue, JiraConfig.issueFixedComment)) {
StringBuilder comment = new StringBuilder();
comment.append(JiraConfig.issueFixedComment);
if (!transitioned) {
comment.append(JiraConfig.issueCloseComment);
}
if (!jira.getSelf().equalsIgnoreCase(issue.getAssignee().getName())) {
comment.append(" [~").append(issue.getAssignee().getName()).append("]");
}
issue.addComment(comment.toString());
}
System.out.print("\n");
}
public void processBugs(List vulnerabilities) throws Exception {
for (Vulnerability vulnerability : vulnerabilities) {
processVulnerability(vulnerability);
}
if (jiraConfig.isCloseAllowed()) {
StringBuilder jql = new StringBuilder();
jql.append("project = ").append(project)
.append(" AND labels = ").append("\"").append(jiraConfig.getAutomationLabel()).append("\"")
.append(" AND labels = ").append("\"").append(repo).append("\"")
.append(" AND issuetype = \"").append(jiraConfig.getIssueType()).append("\"");
for (String status : jiraConfig.getClosedStatuses()) {
jql.append(" AND status != \"").append(status).append("\"");
}
List issues = jira.searchIssues(jql.toString(), JiraConfig.maxSearchResult).issues;
for (Issue issue : issues) {
if (!isVulnerabilityExists(issue, vulnerabilities)) {
closeIssue(issue);
}
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy