fix(测试跟踪): Jira图片不能匿名访问

--bug=1013769 --user=陈建星 【测试跟踪】github#13768,项目MS创建缺陷中含有图片-点击同步缺陷到JIRA-MS缺陷中的图片消失-JIRA中的图片还在 https://www.tapd.cn/55049933/s/1181267
This commit is contained in:
chenjianxing 2022-06-14 15:21:21 +08:00 committed by jianxing
parent e82917ab8c
commit 9c9bf320e9
6 changed files with 53 additions and 9 deletions

View File

@ -26,8 +26,8 @@ public class ResourceController {
} }
@GetMapping(value = "/md/get/url") @GetMapping(value = "/md/get/url")
public ResponseEntity<byte[]> getFileByUrl(@RequestParam ("url") String url) { public ResponseEntity<byte[]> getFileByUrl(@RequestParam ("url") String url, @RequestParam (value = "platform", required = false) String platform) {
return resourceService.getMdImageByUrl(url); return resourceService.getMdImageByUrl(url, platform);
} }
@GetMapping(value = "/ui/get") @GetMapping(value = "/ui/get")

View File

@ -3,8 +3,12 @@ package io.metersphere.service;
import io.metersphere.commons.exception.MSException; import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.utils.FileUtils; import io.metersphere.commons.utils.FileUtils;
import io.metersphere.commons.utils.LogUtil; import io.metersphere.commons.utils.LogUtil;
import io.metersphere.commons.utils.SessionUtils;
import io.metersphere.controller.request.MdUploadRequest; import io.metersphere.controller.request.MdUploadRequest;
import io.metersphere.i18n.Translator; import io.metersphere.i18n.Translator;
import io.metersphere.track.issue.IssueFactory;
import io.metersphere.track.request.testcase.IssuesRequest;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.io.FileSystemResource; import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod; import org.springframework.http.HttpMethod;
@ -96,12 +100,20 @@ public class ResourceService {
* 如果当前访问地址是 https直接访问 http 的图片资源 * 如果当前访问地址是 https直接访问 http 的图片资源
* 由于浏览器的安全机制http 会被转成 https * 由于浏览器的安全机制http 会被转成 https
* @param url * @param url
* @param platform
* @return * @return
*/ */
public ResponseEntity<byte[]> getMdImageByUrl(String url) { public ResponseEntity<byte[]> getMdImageByUrl(String url, String platform) {
if (url.contains("md/get/url")) { if (url.contains("md/get/url")) {
MSException.throwException(Translator.get("invalid_parameter")); MSException.throwException(Translator.get("invalid_parameter"));
} }
if (StringUtils.isNotBlank(platform)) {
IssuesRequest issuesRequest = new IssuesRequest();
issuesRequest.setProjectId(SessionUtils.getCurrentProjectId());
issuesRequest.setWorkspaceId(SessionUtils.getCurrentWorkspaceId());
return IssueFactory.createPlatform(platform, issuesRequest)
.proxyForGet(url, byte[].class);
}
return restTemplate.exchange(url, HttpMethod.GET, null, byte[].class); return restTemplate.exchange(url, HttpMethod.GET, null, byte[].class);
} }
} }

View File

@ -34,6 +34,7 @@ import org.jsoup.Jsoup;
import org.jsoup.nodes.Document; import org.jsoup.nodes.Document;
import org.jsoup.safety.Whitelist; import org.jsoup.safety.Whitelist;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import org.springframework.util.MultiValueMap; import org.springframework.util.MultiValueMap;
@ -372,12 +373,14 @@ public abstract class AbstractIssuePlatform implements IssuesPlatform {
while (matcher.find()) { while (matcher.find()) {
try { try {
String path = matcher.group(2); String path = matcher.group(2);
if (path.contains("/resource/md/get/")) { // 兼容旧数据 if (!path.contains("/resource/md/get/url")) {
String name = path.substring(path.indexOf("/resource/md/get/") + 17); if (path.contains("/resource/md/get/")) { // 兼容旧数据
files.add(new File(FileUtils.MD_IMAGE_DIR + "/" + name)); String name = path.substring(path.indexOf("/resource/md/get/") + 17);
} else if (path.contains("/resource/md/get")) { // 新数据走这里 files.add(new File(FileUtils.MD_IMAGE_DIR + "/" + name));
String name = path.substring(path.indexOf("/resource/md/get") + 26); } else if (path.contains("/resource/md/get")) { // 新数据走这里
files.add(new File(FileUtils.MD_IMAGE_DIR + "/" + URLDecoder.decode(name, "UTF-8"))); String name = path.substring(path.indexOf("/resource/md/get") + 26);
files.add(new File(FileUtils.MD_IMAGE_DIR + "/" + URLDecoder.decode(name, "UTF-8")));
}
} }
} catch (Exception e) { } catch (Exception e) {
LogUtil.error(e.getMessage(), e); LogUtil.error(e.getMessage(), e);
@ -599,4 +602,9 @@ public abstract class AbstractIssuePlatform implements IssuesPlatform {
return null; return null;
} }
@Override
public ResponseEntity proxyForGet(String url, Class responseEntityClazz) {
return null;
}
} }

View File

@ -10,6 +10,7 @@ import io.metersphere.track.issue.domain.PlatformUser;
import io.metersphere.track.request.testcase.EditTestCaseRequest; import io.metersphere.track.request.testcase.EditTestCaseRequest;
import io.metersphere.track.request.testcase.IssuesRequest; import io.metersphere.track.request.testcase.IssuesRequest;
import io.metersphere.track.request.testcase.IssuesUpdateRequest; import io.metersphere.track.request.testcase.IssuesUpdateRequest;
import org.springframework.http.ResponseEntity;
import java.util.List; import java.util.List;
@ -105,4 +106,11 @@ public interface IssuesPlatform {
* @param type add or edit * @param type add or edit
*/ */
void updateDemandHyperLink(EditTestCaseRequest request, Project project, String type); void updateDemandHyperLink(EditTestCaseRequest request, Project project, String type);
/**
* Get请求的代理
* @param url
* @return
*/
ResponseEntity proxyForGet(String url, Class responseEntityClazz);
} }

View File

@ -28,10 +28,13 @@ import io.metersphere.track.service.IssuesService;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringEscapeUtils; import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.client.HttpClientErrorException;
import java.io.File; import java.io.File;
import java.net.URLDecoder; import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.Instant; import java.time.Instant;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.ZoneId; import java.time.ZoneId;
@ -101,6 +104,8 @@ public class JiraPlatform extends AbstractIssuePlatform {
JSONObject attachment = attachments.getJSONObject(i); JSONObject attachment = attachments.getJSONObject(i);
String filename = attachment.getString("filename"); String filename = attachment.getString("filename");
String content = attachment.getString("content"); String content = attachment.getString("content");
content = "/resource/md/get/url?platform=Jira&url=" + URLEncoder.encode(content, StandardCharsets.UTF_8);
if (StringUtils.contains(attachment.getString("mimeType"), "image")) { if (StringUtils.contains(attachment.getString("mimeType"), "image")) {
String contentUrl = "![" + filename + "](" + content + ")"; String contentUrl = "![" + filename + "](" + content + ")";
fileContentMap.put(filename, contentUrl); fileContentMap.put(filename, contentUrl);
@ -124,6 +129,8 @@ public class JiraPlatform extends AbstractIssuePlatform {
// 解析标签内容 // 解析标签内容
String name = getHyperLinkPathForImg("\\!\\[(.*?)\\]", StringEscapeUtils.unescapeJava(splitStr)); String name = getHyperLinkPathForImg("\\!\\[(.*?)\\]", StringEscapeUtils.unescapeJava(splitStr));
String path = getHyperLinkPathForImg("\\|(.*?)\\)", splitStr); String path = getHyperLinkPathForImg("\\|(.*?)\\)", splitStr);
path = "/resource/md/get/url?platform=Jira&url=" + URLEncoder.encode(path, StandardCharsets.UTF_8);
// 解析标签内容为图片超链接格式进行替换 // 解析标签内容为图片超链接格式进行替换
description = description.replace(splitStr, "\n\n![" + name + "](" + path + ")"); description = description.replace(splitStr, "\n\n![" + name + "](" + path + ")");
} }
@ -807,4 +814,8 @@ public class JiraPlatform extends AbstractIssuePlatform {
} }
return false; return false;
} }
public ResponseEntity proxyForGet(String url, Class responseEntityClazz) {
return jiraClientV2.proxyForGet(url, responseEntityClazz);
}
} }

View File

@ -273,4 +273,9 @@ public abstract class JiraAbstractClient extends BaseClient {
MSException.throwException(e.getMessage()); MSException.throwException(e.getMessage());
} }
} }
public ResponseEntity proxyForGet(String url, Class responseEntityClazz) {
LogUtil.info("jira proxyForGet: " + url);
return restTemplate.exchange(url, HttpMethod.GET, getAuthHttpEntity(), responseEntityClazz);
}
} }