PageRenderTime 51ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/jira-project/jira-components/jira-core/src/main/java/com/atlassian/jira/plugin/issueview/DefaultIssueViewURLHandler.java

https://bitbucket.org/ahmed_bilal_360factors/jira7-core
Java | 234 lines | 185 code | 38 blank | 11 comment | 42 complexity | d1d29ac4abb710741cbd4f28d19653ed MD5 | raw file
Possible License(s): Apache-2.0
  1. package com.atlassian.jira.plugin.issueview;
  2. import com.atlassian.jira.component.ComponentAccessor;
  3. import com.atlassian.jira.issue.Issue;
  4. import com.atlassian.jira.issue.IssueManager;
  5. import com.atlassian.jira.issue.search.SearchException;
  6. import com.atlassian.jira.issue.search.SearchProvider;
  7. import com.atlassian.jira.issue.search.SearchResults;
  8. import com.atlassian.jira.issue.views.IssuePdfView;
  9. import com.atlassian.jira.jql.builder.JqlQueryBuilder;
  10. import com.atlassian.jira.plugin.searchrequestview.HttpRequestHeaders;
  11. import com.atlassian.jira.security.PermissionManager;
  12. import com.atlassian.jira.security.Permissions;
  13. import com.atlassian.jira.user.ApplicationUser;
  14. import com.atlassian.jira.user.util.UserUtil;
  15. import com.atlassian.jira.web.bean.PagerFilter;
  16. import com.atlassian.plugin.PluginAccessor;
  17. import com.atlassian.query.Query;
  18. import com.atlassian.seraph.util.RedirectUtils;
  19. import org.apache.commons.lang.StringEscapeUtils;
  20. import org.apache.commons.lang.StringUtils;
  21. import java.io.InputStream;
  22. import javax.servlet.ServletException;
  23. import javax.servlet.http.HttpServletRequest;
  24. import javax.servlet.http.HttpServletResponse;
  25. import java.io.IOException;
  26. /**
  27. * This class takes care of handling the creation of URLs for the issue view plugin, as well as handling the incoming
  28. * requests
  29. */
  30. public class DefaultIssueViewURLHandler implements IssueViewURLHandler {
  31. private final PluginAccessor pluginAccessor;
  32. private final IssueManager issueManager;
  33. private final PermissionManager permissionManager;
  34. private final SearchProvider searchProvider;
  35. private final IssueViewRequestParamsHelper issueViewRequestParamsHelper;
  36. private final UserUtil userUtil;
  37. public DefaultIssueViewURLHandler(PluginAccessor pluginAccessor, IssueManager issueManager, PermissionManager permissionManager, SearchProvider searchProvider, IssueViewRequestParamsHelper issueViewRequestParamsHelper, final UserUtil userUtil) {
  38. this.pluginAccessor = pluginAccessor;
  39. this.issueManager = issueManager;
  40. this.permissionManager = permissionManager;
  41. this.searchProvider = searchProvider;
  42. this.issueViewRequestParamsHelper = issueViewRequestParamsHelper;
  43. this.userUtil = userUtil;
  44. }
  45. public String getURLWithoutContextPath(IssueViewModuleDescriptor moduleDescriptor, String issueKey) {
  46. return "/si/" + moduleDescriptor.getCompleteKey() + "/" + issueKey + "/" + issueKey + "." + moduleDescriptor.getFileExtension();
  47. }
  48. /**
  49. * @return A sample URL to be used for used for error messages
  50. */
  51. private static String getSampleURL() {
  52. return "/si/jira.issueviews:xml/JRA-10/JRA-10.xml";
  53. }
  54. @edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "HRS_REQUEST_PARAMETER_TO_HTTP_HEADER", justification = "JIRA has a HeaderSanitisingFilter that protects against this")
  55. public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws IOException {
  56. String pathInfo = request.getPathInfo();
  57. // JRA-15847: check for null path
  58. if (StringUtils.isBlank(pathInfo)) {
  59. response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid path format. Path should be of format " + getSampleURL());
  60. return;
  61. }
  62. //trim any leading slash
  63. if (pathInfo.startsWith("/")) {
  64. pathInfo = pathInfo.substring(1);
  65. }
  66. int firstSlashLocation = pathInfo.indexOf("/");
  67. if (firstSlashLocation == -1) {
  68. response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid path format. Path should be of format " + getSampleURL());
  69. return;
  70. }
  71. String pluginKey = pathInfo.substring(0, firstSlashLocation);
  72. if (pathInfo.lastIndexOf(".")!=-1){
  73. int lastS = pathInfo.lastIndexOf("/");
  74. String str = pathInfo.substring(lastS +1, pathInfo.length());
  75. if (str.indexOf(".")==-1){
  76. if (!str.equalsIgnoreCase("PDF")){
  77. pathInfo+="/"+str+".PDF";
  78. }
  79. }
  80. }
  81. int secondSlashLocation = pathInfo.indexOf("/", firstSlashLocation + 1);
  82. if (secondSlashLocation == -1) {
  83. response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid path format. Path should be of format " + getSampleURL());
  84. return;
  85. }
  86. String issueKey = pathInfo.substring(firstSlashLocation + 1, secondSlashLocation);
  87. ApplicationUser user = null;
  88. if (request.getRemoteUser() != null) {
  89. user = userUtil.getUserByName(request.getRemoteUser());
  90. if (user == null) {
  91. response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Could not find a user with the username " + StringEscapeUtils.escapeHtml(request.getRemoteUser()));
  92. return;
  93. }
  94. }
  95. IssueViewModuleDescriptor moduleDescriptor = getPluginModule(pluginKey);
  96. if (moduleDescriptor == null) {
  97. response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Could not find any enabled plugin with key " + StringEscapeUtils.escapeHtml(pluginKey));
  98. return;
  99. }
  100. Issue issue;
  101. if ("index".equalsIgnoreCase(request.getParameter("jira.issue.searchlocation"))) {
  102. issue = getIssueFromIndex(issueKey, user); // for functional tests, we want to do testing with the index
  103. // we don't need permission checks here, as they are done by the index
  104. } else {
  105. issue = getIssueFromDatabase(issueKey); // by default get things from the database
  106. if (issue != null && !issue.getKey().equals(issueKey)) {
  107. //found a moved issue! Redirect to it...
  108. String contextPath = request.getContextPath() != null ? request.getContextPath() : "";
  109. String queryString = request.getQueryString() != null ? '?' + request.getQueryString() : "";
  110. response.sendRedirect(contextPath + getURLWithoutContextPath(moduleDescriptor, issue.getKey()) + queryString);
  111. return; //return to avoid double send errors
  112. }
  113. if (issue != null && !permissionManager.hasPermission(Permissions.BROWSE, issue, user)) {
  114. if (user == null) {
  115. response.sendRedirect(RedirectUtils.getLoginUrl(request));
  116. } else {
  117. runJSP(request, response, "/secure/views/permissionviolation.jsp");
  118. }
  119. return;
  120. }
  121. }
  122. if (issue == null) {
  123. response.sendError(HttpServletResponse.SC_NOT_FOUND, "Could not find issue with issue key " + StringEscapeUtils.escapeHtml(issueKey));
  124. return;
  125. }
  126. IssueView view = moduleDescriptor.getIssueView();
  127. IssueViewFieldParams issueViewFieldParams = issueViewRequestParamsHelper.getIssueViewFieldParams(request.getParameterMap());
  128. if (issueViewFieldParams.isCustomViewRequested() && !issueViewFieldParams.isAnyFieldDefined()) {
  129. response.sendError(HttpServletResponse.SC_BAD_REQUEST, "No valid field defined for issue custom view");
  130. return;
  131. }
  132. IssueViewRequestParams issueViewRequestParams = new IssueViewRequestParamsImpl(issueViewFieldParams);
  133. int lastSlashLocation = pathInfo.lastIndexOf("/");
  134. String pdf = pathInfo.substring(lastSlashLocation+1, pathInfo.length());
  135. pdf = pdf.substring(pdf.lastIndexOf(".")+1);
  136. String content = view.getContent(issue, issueViewRequestParams);
  137. StringBuilder stringBuilder = new StringBuilder();
  138. stringBuilder.append(view.getContent(issue, issueViewRequestParams));
  139. if (!"true".equalsIgnoreCase(request.getParameter(NO_HEADERS_PARAMETER)) && !pdf.equalsIgnoreCase("pdf")) {
  140. response.setContentType(moduleDescriptor.getContentType() + ";charset=" + ComponentAccessor.getApplicationProperties().getEncoding());
  141. view.writeHeaders(issue, new HttpRequestHeaders(response), issueViewRequestParams);
  142. }
  143. if (pdf.equalsIgnoreCase("pdf")){
  144. IssuePdfView issuePdfView = new IssuePdfView();
  145. issuePdfView.writeHeaders(issue, new HttpRequestHeaders(response), issueViewRequestParams);
  146. response.setContentType("application/pdf");
  147. InputStream iStream = issuePdfView.convertHTML(content);
  148. int bytes;
  149. while ((bytes = iStream.read()) != -1) {
  150. response.getOutputStream().write(bytes);
  151. }
  152. }
  153. else{
  154. response.getWriter().write(content);
  155. }
  156. }
  157. private IssueViewModuleDescriptor getPluginModule(String pluginKey) {
  158. try {
  159. return (IssueViewModuleDescriptor) pluginAccessor.getEnabledPluginModule(pluginKey);
  160. } catch (ClassCastException e) {
  161. return null;
  162. } catch (IllegalArgumentException e) {
  163. return null;
  164. }
  165. }
  166. private void runJSP(HttpServletRequest request, HttpServletResponse response, final String jspPath) throws IOException {
  167. try {
  168. request.getRequestDispatcher(jspPath).forward(request, response);
  169. } catch (ServletException e) {
  170. throw new RuntimeException("Could not load java server page", e);
  171. }
  172. }
  173. private Issue getIssueFromDatabase(String issueKey) {
  174. return issueManager.getIssueObject(issueKey);
  175. }
  176. private Issue getIssueFromIndex(String issueKey, ApplicationUser user) {
  177. final Query query;
  178. if (StringUtils.isNotBlank(issueKey)) {
  179. query = JqlQueryBuilder.newBuilder().where().issue(issueKey).buildQuery();
  180. } else {
  181. query = JqlQueryBuilder.newBuilder().buildQuery();
  182. }
  183. try {
  184. SearchResults searchResults = searchProvider.search(query, user, PagerFilter.getUnlimitedFilter());
  185. if (searchResults.getTotal() > 1) {
  186. throw new IllegalStateException("More than one issue returned when searching index for issue key " + issueKey);
  187. }
  188. if (searchResults.getTotal() == 0) {
  189. return null;
  190. }
  191. return searchResults.getIssues().iterator().next();
  192. } catch (SearchException e) {
  193. throw new RuntimeException(e);
  194. }
  195. }
  196. }