Browse Source

open

master
pioneer 1 year ago
commit
d20bd24a52
  1. 6
      README.md
  2. BIN
      lib/drm-edi-3.1.1.jar
  3. 22
      plugin.xml
  4. 42
      src/main/java/com/fr/plugin/xx/zyjn/decode/DecodeConfig.java
  5. 97
      src/main/java/com/fr/plugin/xx/zyjn/decode/GlobalFilter.java
  6. 27
      src/main/java/com/fr/plugin/xx/zyjn/decode/LRGT.java
  7. 120
      src/main/java/com/fr/plugin/xx/zyjn/decode/LogUtils.java
  8. 13
      src/main/java/com/fr/plugin/xx/zyjn/decode/PluginConstants.java
  9. 64
      src/main/java/com/fr/plugin/xx/zyjn/decode/decode/BodyReaderHttpServletRequestWrapper.java
  10. 206
      src/main/java/com/fr/plugin/xx/zyjn/decode/decode/DecodeFilter.java
  11. 28
      src/main/java/com/fr/plugin/xx/zyjn/decode/encode/EncodeExportExtensionProvider.java
  12. 48
      src/main/java/com/fr/plugin/xx/zyjn/decode/encode/EncryptExporter.java
  13. 190
      src/main/java/com/fr/plugin/xx/zyjn/decode/encode/EncryptOutputStream.java
  14. 25
      src/main/java/com/fr/plugin/xx/zyjn/decode/encode/EncryptResponse.java
  15. 71
      src/main/java/com/fr/plugin/xx/zyjn/decode/encode/bi/EncodeFilter.java
  16. 18
      src/main/java/com/fr/plugin/xx/zyjn/decode/encode/bi/ExportFunc.java
  17. 169
      src/main/java/com/fr/plugin/xx/zyjn/decode/encode/bi/FileUtil.java
  18. 70
      src/main/java/com/fr/plugin/xx/zyjn/decode/encode/bi/ResponseWrapperImpl.java
  19. 89
      src/main/java/com/fr/plugin/xx/zyjn/decode/util/GZIPUtils.java

6
README.md

@ -0,0 +1,6 @@
# open-JSD-10202
JSD-10202 客户的文件都是加密的,所以数据填报时上传Excel动作需要先跑一下他们的解密应用,再读取到填报页面;同样在使用报表的导出功能时,需要先跑一下他们的加密应用,保障导出的文件是经过加密的\
免责说明:该源码为第三方爱好者提供,不保证源码和方案的可靠性,也不提供任何形式的源码教学指导和协助!\
仅作为开发者学习参考使用!禁止用于任何商业用途!\
为保护开发者隐私,开发者信息已隐去!若原开发者希望公开自己的信息,可联系【pioneer】处理。

BIN
lib/drm-edi-3.1.1.jar

Binary file not shown.

22
plugin.xml

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<plugin>
<id>com.fr.plugin.xx.zyjn.decode</id>
<name><![CDATA[中冶焦耐加密解密_EK]]></name>
<active>yes</active>
<version>1.0</version>
<env-version>10.0</env-version>
<jartime>2018-07-31</jartime>
<vendor>fr.open</vendor>
<description><![CDATA[中冶焦耐加密解密_jsd-10202]]></description>
<change-notes><![CDATA[
[2022-06-28]【1.0】初始化插件。<br/>
]]></change-notes>
<extra-decision>
<GlobalRequestFilterProvider class="com.fr.plugin.xx.zyjn.decode.GlobalFilter"/>
</extra-decision>
<!--<extra-report>
<ExportExtensionProcessor class="com.fr.plugin.xx.zyjn.decode.encode.EncodeExportExtensionProvider"/>
</extra-report>-->
<function-recorder class="com.fr.plugin.xx.zyjn.decode.decode.DecodeFilter"/>
<lifecycle-monitor class="com.fr.plugin.xx.zyjn.decode.LRGT"/>
</plugin>

42
src/main/java/com/fr/plugin/xx/zyjn/decode/DecodeConfig.java

@ -0,0 +1,42 @@
package com.fr.plugin.xx.zyjn.decode;
import com.fr.config.*;
import com.fr.config.holder.Conf;
import com.fr.config.holder.factory.Holders;
/**
* @author xx
* @since 2021/12/04
*/
@Visualization(category = "加解密配置")
public class DecodeConfig extends DefaultConfiguration {
private static volatile DecodeConfig config = null;
public static DecodeConfig getInstance() {
if (config == null) {
config = ConfigContext.getConfigInstance(DecodeConfig.class);
}
return config;
}
@Identifier(value = "debugSwitch", name = "插件调试开关", description = "日志调试模式", status = Status.SHOW)
private Conf<Boolean> debugSwitch = Holders.simple(true);
public Boolean getDebugSwitch() {
return this.debugSwitch.get();
}
public void setDebugSwitch(Boolean debugSwitch) {
this.debugSwitch.set(debugSwitch);
}
@Override
public Object clone() throws CloneNotSupportedException {
DecodeConfig cloned = (DecodeConfig) super.clone();
cloned.debugSwitch = (Conf<Boolean>) debugSwitch.clone();
return cloned;
}
}

97
src/main/java/com/fr/plugin/xx/zyjn/decode/GlobalFilter.java

@ -0,0 +1,97 @@
package com.fr.plugin.xx.zyjn.decode;
import com.fr.decision.fun.impl.AbstractGlobalRequestFilterProvider;
import com.fr.intelli.record.Focus;
import com.fr.intelli.record.Original;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.context.PluginContexts;
import com.fr.plugin.xx.zyjn.decode.decode.DecodeFilter;
import com.fr.plugin.transform.FunctionRecorder;
import com.fr.record.analyzer.EnableMetrics;
import com.fr.stable.StringUtils;
import com.fr.stable.fun.Authorize;
import com.fr.web.utils.WebUtils;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author xx
* @date 2020/11/20
*/
@FunctionRecorder
@Authorize(callSignKey = PluginConstants.PLUGIN_ID)
@EnableMetrics
public class GlobalFilter extends AbstractGlobalRequestFilterProvider {
@Override
public String filterName() {
return "zdgl";
}
@Override
@Focus(id = PluginConstants.PLUGIN_ID, text = PluginConstants.PLUGIN_NAME, source = Original.PLUGIN)
public String[] urlPatterns() {
if (PluginContexts.currentContext().isAvailable()) {
return new String[]{
"/*"
};
} else {
return new String[]{"/neverbeused"};
}
}
@Override
public void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain filterChain) {
if (isDecode(req)) {
new DecodeFilter().doFilter(req, res, filterChain);
return;
}
/*if (isEncode(req)) {
new EncodeFilter().doFilter(req, res, filterChain);
return;
}*/
try {
filterChain.doFilter(req, res);
} catch (IOException e) {
FineLoggerFactory.getLogger().error(e.getMessage());
} catch (ServletException e) {
FineLoggerFactory.getLogger().error(e.getMessage());
}
}
private boolean isDecode(HttpServletRequest req) {
if (req.getRequestURI().endsWith("attach/upload")) {
return true;
}
if (req.getRequestURI().endsWith("/dataset/upload")) {
return true;
}
String op = WebUtils.getHTTPRequestParameter(req, "op");
String cmd = WebUtils.getHTTPRequestParameter(req, "cmd");
if (StringUtils.equals("fr_attach", op) && StringUtils.equals("ah_upload", cmd)) {
return true;
}
if (StringUtils.equals("fr_write", op) && StringUtils.equals("imp_w_excel_data", cmd)) {
return true;
}
return false;
}
private boolean isEncode(HttpServletRequest req) {
String op = WebUtils.getHTTPRequestParameter(req, "op");
String cmd = WebUtils.getHTTPRequestParameter(req, "cmd");
if (StringUtils.equals("fr_attach", op) && StringUtils.equals("ah_download", cmd)) {
return true;
}
if (StringUtils.equals("customcommit", op) && StringUtils.equals("downloadfile", cmd)) {
return true;
}
return false;
}
}

27
src/main/java/com/fr/plugin/xx/zyjn/decode/LRGT.java

@ -0,0 +1,27 @@
package com.fr.plugin.xx.zyjn.decode;
import com.fr.plugin.context.PluginContext;
import com.fr.plugin.observer.inner.AbstractPluginLifecycleMonitor;
/**
* 配置信息初始化
*/
public class LRGT extends AbstractPluginLifecycleMonitor {
@Override
public void afterRun(PluginContext pluginContext) {
DecodeConfig.getInstance();
}
@Override
public void beforeStop(PluginContext pluginContext) {
}
@Override
public void beforeUninstall(PluginContext pluginContext) {
}
@Override
public void afterInstall(PluginContext var1) {
}
}

120
src/main/java/com/fr/plugin/xx/zyjn/decode/LogUtils.java

@ -0,0 +1,120 @@
package com.fr.plugin.xx.zyjn.decode;
import com.fr.log.FineLoggerFactory;
import com.fr.log.FineLoggerProvider;
import com.fr.plugin.context.PluginContexts;
import com.fr.stable.StringUtils;
/**
* @author xx
* @since 2021/12/04
*/
public final class LogUtils {
private static final String DEBUG_PREFIX = "[插件调试] ";
private static String LOG_PREFIX = PluginConstants.PLUGIN_NAME;
private static final String PLUGIN_VERSION;
private static final FineLoggerProvider LOGGER = FineLoggerFactory.getLogger();
static {
String version = PluginContexts.currentContext().getMarker().getVersion();
if (StringUtils.isNotBlank(version)) {
PLUGIN_VERSION = "[v" + version + "] ";
} else {
PLUGIN_VERSION = "[unknown version] ";
}
LOG_PREFIX = LOG_PREFIX + PLUGIN_VERSION;
}
public static void setPrefix(String prefix) {
if (prefix != null) {
LOG_PREFIX = prefix;
}
}
public static boolean isDebugEnabled() {
return LOGGER.isDebugEnabled();
}
public static void debug(String s) {
LOGGER.debug(LOG_PREFIX + s);
}
public static void debug(String s, Object... objects) {
LOGGER.debug(LOG_PREFIX + s, objects);
}
public static void debug(String s, Throwable throwable) {
LOGGER.debug(LOG_PREFIX + s, throwable);
}
public static void debug4plugin(String s) {
if (DecodeConfig.getInstance().getDebugSwitch()) {
LOGGER.error(DEBUG_PREFIX + LOG_PREFIX + s);
} else {
LOGGER.debug(LOG_PREFIX + s);
}
}
public static void debug4plugin(String s, Object... objects) {
if (DecodeConfig.getInstance().getDebugSwitch()) {
LOGGER.error(DEBUG_PREFIX + LOG_PREFIX + s, objects);
} else {
LOGGER.debug(LOG_PREFIX + s, objects);
}
}
public static void debug4plugin(String s, Throwable throwable) {
if (DecodeConfig.getInstance().getDebugSwitch()) {
LOGGER.error(DEBUG_PREFIX + LOG_PREFIX + s, throwable);
} else {
LOGGER.debug(LOG_PREFIX + s, throwable);
}
}
public static boolean isInfoEnabled() {
return LOGGER.isInfoEnabled();
}
public static void info(String s) {
LOGGER.info(LOG_PREFIX + s);
}
public static void info(String s, Object... objects) {
LOGGER.info(LOG_PREFIX + s, objects);
}
public static void warn(String s) {
LOGGER.warn(LOG_PREFIX + s);
}
public static void warn(String s, Object... objects) {
LOGGER.warn(LOG_PREFIX + s, objects);
}
public static void warn(String s, Throwable throwable) {
LOGGER.warn(LOG_PREFIX + s, throwable);
}
public static void warn(Throwable throwable, String s, Object... objects) {
LOGGER.warn(throwable, LOG_PREFIX + s, objects);
}
public static void error(String s) {
LOGGER.error(LOG_PREFIX + s);
}
public static void error(String s, Object... objects) {
LOGGER.error(LOG_PREFIX + s, objects);
}
public static void error(String s, Throwable throwable) {
LOGGER.error(LOG_PREFIX + s, throwable);
}
public static void error(Throwable throwable, String s, Object... objects) {
LOGGER.error(throwable, LOG_PREFIX + s, objects);
}
}

13
src/main/java/com/fr/plugin/xx/zyjn/decode/PluginConstants.java

@ -0,0 +1,13 @@
package com.fr.plugin.xx.zyjn.decode;
/**
* @author xx
* @since 2021/12/04
*/
public class PluginConstants {
public static final String PLUGIN_ID = "com.fr.plugin.xx.zyjn.decode";
public static final String PLUGIN_NAME = "加密解密";
}

64
src/main/java/com/fr/plugin/xx/zyjn/decode/decode/BodyReaderHttpServletRequestWrapper.java

@ -0,0 +1,64 @@
package com.fr.plugin.xx.zyjn.decode.decode;
import com.fr.third.jodd.io.StreamUtil;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* @author xx
* @date 2022/03/01
*/
public class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper {
private BufferedReader br;
private byte[] body;
public BodyReaderHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
//this.br = request.getReader();
body = StreamUtil.readBytes(request.getInputStream());
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(getInputStream()));
}
@Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream bais = new ByteArrayInputStream(body);
return new ServletInputStream() {
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener readListener) {
}
@Override
public int read() throws IOException {
return bais.read();
}
};
}
public void setBody(byte[] body) {
this.body = body;
}
}

206
src/main/java/com/fr/plugin/xx/zyjn/decode/decode/DecodeFilter.java

@ -0,0 +1,206 @@
package com.fr.plugin.xx.zyjn.decode.decode;
import cn.net.drm.edi.client.DrmAgent;
import cn.net.drm.edi.client.DrmAgentInf;
import cn.net.drm.edi.exception.DrmException;
import com.fr.base.ServerConfig;
import com.fr.base.core.IgnoreBytesInputStream;
import com.fr.base.core.ParseResult;
import com.fr.base.core.PostParseUtils;
import com.fr.data.NetworkHelper;
import com.fr.decision.authority.data.User;
import com.fr.decision.fun.impl.AbstractGlobalRequestFilterProvider;
import com.fr.decision.mobile.terminal.TerminalHandler;
import com.fr.decision.webservice.v10.config.ConfigService;
import com.fr.decision.webservice.v10.login.LoginService;
import com.fr.decision.webservice.v10.login.TokenResource;
import com.fr.decision.webservice.v10.user.UserService;
import com.fr.general.CommonIOUtils;
import com.fr.io.utils.ResourceIOUtils;
import com.fr.plugin.context.PluginContexts;
import com.fr.plugin.xx.zyjn.decode.LogUtils;
import com.fr.plugin.xx.zyjn.decode.PluginConstants;
import com.fr.plugin.transform.FunctionRecorder;
import com.fr.stable.fun.Authorize;
import com.fr.stable.web.Device;
import com.fr.third.org.apache.commons.io.IOUtils;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.UUID;
/**
* @author xx
* @date 2022/03/01
*/
@FunctionRecorder
@Authorize(callSignKey = PluginConstants.PLUGIN_ID)
public class DecodeFilter extends AbstractGlobalRequestFilterProvider {
private static final byte[] NEW_LINE_BYTES = new byte[]{13, 10};
private static final byte[] BOUNDARY_END = new byte[]{45, 45};
private static final String TMP_PATH = System.getProperty("java.io.tmpdir");
@Override
public String filterName() {
return "decode";
}
@Override
public String[] urlPatterns() {
String servletPathName = "decision";
try {
servletPathName = ConfigService.getInstance().getBasicParam().getServletPathName();
} catch (Exception e) {
LogUtils.error(e.getMessage(), e);
}
if (PluginContexts.currentContext().isAvailable()) {
return new String[]{
"/" + servletPathName + "/v10/attach/upload",
"/" + servletPathName + "/v10/dataset/upload",
"/" + servletPathName + "/view/report",
};
} else {
return new String[]{"/aaaa"};
}
}
@Override
public void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain filterChain) {
BodyReaderHttpServletRequestWrapper wrapper = null;
try {
DrmAgentInf instance;
instance = DrmAgent.getInstance();
wrapper = new BodyReaderHttpServletRequestWrapper(req);
User user = getUser(req);
if (user == null) {
LogUtils.debug4plugin("current user is null,not decrypted");
filter(wrapper, res, filterChain);
return;
}
InputStream inputStream = wrapper.getInputStream();
ParseResult parseResult = PostParseUtils.parse(inputStream, req.getCharacterEncoding());
InputStream fis = new IgnoreBytesInputStream(inputStream, this.concat(this.concat(NEW_LINE_BYTES, parseResult.getBoundary().getBytes()), BOUNDARY_END));
LogUtils.debug4plugin("record file request url is {}", req.getRequestURI() + req.getQueryString());
File file = saveTmp(fis, parseResult.getFileName());
boolean encrypted = instance.isEncrypted(file);
LogUtils.debug4plugin("current files encrypted is {}", encrypted);
if (!encrypted) {
filter(wrapper, res, filterChain);
return;
}
decode(req, wrapper, parseResult, file, instance);
} catch (Exception e) {
LogUtils.error(e.getMessage(), e);
}
if (wrapper != null) {
filter(wrapper, res, filterChain);
return;
}
}
private void decode(HttpServletRequest req, BodyReaderHttpServletRequestWrapper wrapper, ParseResult parseResult, File file, DrmAgentInf instance) throws DrmException, UnsupportedEncodingException, FileNotFoundException {
//File file = saveTmp(fis,parseResult.getFileName());
long decrypt = instance.decrypt(file);
LogUtils.debug4plugin("decode file size is {}", decrypt);
wrapper.setBody(handleBody(req, CommonIOUtils.inputStream2Bytes(new FileInputStream(file)), parseResult, req.getCharacterEncoding() == null ? ServerConfig.getInstance().getServerCharset() : req.getCharacterEncoding()));
file.delete();
LogUtils.debug4plugin("delete temp file");
}
private User getUser(HttpServletRequest req) {
try {
return UserService.getInstance().getUserByRequestCookie(req);
} catch (Exception e) {
}
return null;
}
private File saveTmp(InputStream input, String filename) {
if (!ResourceIOUtils.isDirectoryExist(TMP_PATH)) {
ResourceIOUtils.createDirectory(TMP_PATH);
}
String path = TMP_PATH + File.separator + UUID.randomUUID() + filename.substring(filename.indexOf("."));
File file = new File(path);
FileOutputStream outputStream = null;
if (!file.exists()) {
try {
file.createNewFile();
outputStream = new FileOutputStream(file.getPath());
IOUtils.copyLarge(input, outputStream);
LogUtils.debug4plugin("save tmp file path is {}", path);
} catch (IOException e) {
LogUtils.error(e.getMessage(), e);
} finally {
try {
input.close();
outputStream.flush();
outputStream.close();
} catch (IOException e) {
LogUtils.error(e.getMessage(), e);
}
}
}
return new File(path);
}
private void filter(HttpServletRequest req, HttpServletResponse res, FilterChain filterChain) {
try {
filterChain.doFilter(req, res);
} catch (IOException e) {
LogUtils.error(e.getMessage(), e);
} catch (ServletException e) {
LogUtils.error(e.getMessage(), e);
}
}
private boolean isLogin(HttpServletRequest request) {
String oldToken = TokenResource.COOKIE.getToken(request);
return oldToken != null && checkTokenValid(request, (String) oldToken);
}
private boolean checkTokenValid(HttpServletRequest req, String token) {
try {
Device device = NetworkHelper.getDevice(req);
LoginService.getInstance().loginStatusValid(token, TerminalHandler.getTerminal(req, device));
return true;
} catch (Exception ignore) {
}
return false;
}
private byte[] concat(byte[] a, byte[] b) {
byte[] c = new byte[a.length + b.length];
System.arraycopy(a, 0, c, 0, a.length);
System.arraycopy(b, 0, c, a.length, b.length);
return c;
}
private byte[] handleBody(HttpServletRequest req, byte[] body, ParseResult parseResult, String charsetName) throws UnsupportedEncodingException {
byte[] newBody;
byte[] start;
byte[] end;
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(parseResult.getBoundary()).append("\r\n")
.append("Content-Disposition:").append(parseResult.getDispline())
.append("; name=\"").append(parseResult.getFieldName())
.append("\"; filename=\"").append(parseResult.getFileName()).append("\"\r\n")
.append("Content-Type: ").append(req.getContentType()).append("\r\n").append("\r\n");
start = stringBuilder.toString().getBytes(charsetName);
StringBuilder stringBuilder1 = new StringBuilder();
stringBuilder1.append("\r\n").append(parseResult.getBoundary()).append("--\r\n");
end = stringBuilder1.toString().getBytes(charsetName);
newBody = this.concat(this.concat(start, body), end);
return newBody;
}
}

28
src/main/java/com/fr/plugin/xx/zyjn/decode/encode/EncodeExportExtensionProvider.java

@ -0,0 +1,28 @@
package com.fr.plugin.xx.zyjn.decode.encode;
import com.fr.io.collection.ExportCollection;
import com.fr.io.exporter.AppExporter;
import com.fr.plugin.xx.zyjn.decode.LogUtils;
import com.fr.web.core.ReportSessionIDInfor;
import com.fr.web.core.reserve.DefaultExportExtension;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @Author xx
* @Date 2022/3/7
* @Description
**/
public class EncodeExportExtensionProvider extends DefaultExportExtension {
@Override
public ExportCollection createCollection(HttpServletRequest req, HttpServletResponse res,
ReportSessionIDInfor info, String format, String filename, boolean isEmbed) throws Exception {
ExportCollection collection = super.createCollection(req, res, info, format, filename, isEmbed);
LogUtils.debug4plugin("get encode exporter");
AppExporter exporter = collection.getExporter();
collection.setExporter(new EncryptExporter(exporter));
return collection;
}
}

48
src/main/java/com/fr/plugin/xx/zyjn/decode/encode/EncryptExporter.java

@ -0,0 +1,48 @@
package com.fr.plugin.xx.zyjn.decode.encode;
import com.fr.io.exporter.AppExporter;
import com.fr.main.workbook.ResultWorkBook;
import com.fr.page.PageSetCreator;
import com.fr.page.PageSetProvider;
import com.fr.web.core.ReportRepositoryDeal;
import java.io.OutputStream;
/**
* @Author xx
* @Date 2022/3/7
* @Description
**/
public class EncryptExporter implements AppExporter {
private AppExporter original;
public EncryptExporter(AppExporter original) {
this.original = original;
}
@Override
public void export(OutputStream out, ResultWorkBook book) throws Exception {
original.export(new EncryptOutputStream(out), book);
}
@Override
public void export(OutputStream out, PageSetProvider pageSet) throws Exception {
original.export(new EncryptOutputStream(out), pageSet);
}
@Override
public void export(OutputStream out, ResultWorkBook book, PageSetCreator creator, ReportRepositoryDeal repo, int[] sheets) throws Exception {
original.export(new EncryptOutputStream(out), book, creator, repo, sheets);
}
@Override
public void export(OutputStream out, ResultWorkBook book, PageSetProvider pageSet, ReportRepositoryDeal repo, int[] sheets) throws Exception {
original.export(new EncryptOutputStream(out), book, pageSet, repo, sheets);
}
@Override
public void setVersion(Object o) {
original.setVersion(o);
}
}

190
src/main/java/com/fr/plugin/xx/zyjn/decode/encode/EncryptOutputStream.java

@ -0,0 +1,190 @@
package com.fr.plugin.xx.zyjn.decode.encode;
import cn.net.drm.edi.client.DrmAgent;
import cn.net.drm.edi.client.DrmAgentInf;
import cn.net.drm.io.IOUtils;
import com.fr.general.CommonIOUtils;
import com.fr.plugin.xx.zyjn.decode.DecodeConfig;
import com.fr.plugin.xx.zyjn.decode.LogUtils;
import com.fr.plugin.xx.zyjn.decode.encode.bi.FileUtil;
import org.apache.tools.zip.ZipOutputStream;
import javax.servlet.ServletOutputStream;
import javax.servlet.WriteListener;
import java.io.*;
import java.util.UUID;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @Author xx
* @Date 2022/3/3
* @Description
**/
public class EncryptOutputStream extends ServletOutputStream {
private OutputStream original = null;
private boolean closed = false;
private ByteArrayOutputStream crypt = new ByteArrayOutputStream();
public EncryptOutputStream(OutputStream original) {
this.original = original;
}
/**
* 实际加密的代码就在这里实现了
*
* @param bytes
* @param ignore
* @return
*/
public static byte[] encrypt(byte[] bytes, boolean ignore) {
DecodeConfig config = DecodeConfig.getInstance();
/*if (!config.isConfiged()) {
LogUtils.warn("config not finish, not encrypted");
return bytes;
}*/
ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
byte[] header = new byte[256];
bis.mark(256);
byte[] encode = bytes;
OutputStream fos = null;
try {
DrmAgentInf instance = null;
instance = DrmAgent.getInstance();
File tempFile = File.createTempFile("tmp" + UUID.randomUUID().toString(), null);
LogUtils.info("create tmp file path is {}", tempFile.getPath());
bis.read(header);
bis.reset();
boolean isEncryptFile = instance.isEncrypted(tempFile);
if (!isEncryptFile) {
if (FileUtil.isArchiveFile(bytes) && !ignore) {
encode = encodeZip(bytes, instance, config);
} else {
//fos = instance.encryptBasicFile(tempFile, config.getOwnerId(), config.getSecretLevelId());
int len = 0;
byte[] buffer = new byte[1024];
while ((len = bis.read(buffer)) > 0) {
fos.write(buffer, 0, len);
}
fos.flush();
FileInputStream in = new FileInputStream(tempFile);
encode = CommonIOUtils.inputStream2Bytes(in);
tempFile.deleteOnExit();
}
}
} catch (Exception e) {
LogUtils.error(e.getMessage(), e);
} finally {
IOUtils.closeQuietly(bis);
IOUtils.closeQuietly(fos);
}
//假设逆序就是加密了
return encode;
}
private static byte[] encodeZip(byte[] bytes, DrmAgentInf instance, DecodeConfig config) {
File zipFile = null, encodeZipFile = null;
File unzipFileFolder = FileUtil.createTempFolder("tmp_unzip" + UUID.randomUUID().toString());
File zipFileFolder = FileUtil.createTempFolder("tmp_zip" + UUID.randomUUID().toString());
try {
encodeZipFile = FileUtil.createTempFile();
zipFile = FileUtil.createTempFile();
//先缓存文件
com.fr.general.IOUtils.copyBinaryTo(new ByteArrayInputStream(bytes), new FileOutputStream(zipFile));
LogUtils.debug4plugin("save zip file path:{} size is {}", zipFile.getAbsolutePath(), zipFile.getTotalSpace());
//再解压出来
com.fr.general.IOUtils.unzip(zipFile, unzipFileFolder.getAbsolutePath(),"GBK");
LogUtils.debug4plugin("unzip file path is {} file list is {} unzip size is {}", unzipFileFolder.getAbsolutePath(), Stream.of(unzipFileFolder.listFiles()).map(e->e.getName()).collect(Collectors.joining(",")), unzipFileFolder.listFiles().length);
File[] files = unzipFileFolder.listFiles();
ZipOutputStream zipOutputStream = new ZipOutputStream(encodeZipFile);
zipOutputStream.setEncoding("GBK");
for (int i = 0; i < files.length; i++) {
File file = files[i];
//加密复制到另外一个文件夹
String encode = zipFileFolder + File.separator + file.getName();
InputStream bis = new FileInputStream(file);
//加密
OutputStream fos =null;// instance.encryptBasicStream(new FileOutputStream(encode), config.getOwnerId(), config.getSecretLevelId());
int len = 0;
byte[] buffer = new byte[1024];
while ((len = bis.read(buffer)) > 0) {
fos.write(buffer, 0, len);
}
fos.flush();
IOUtils.closeQuietly(bis);
IOUtils.closeQuietly(fos);
LogUtils.debug4plugin("encode file {} to {}", file.getAbsolutePath(), encode);
}
//zip
com.fr.general.IOUtils.zip(zipOutputStream, zipFileFolder);
zipOutputStream.closeEntry();
zipOutputStream.close();
LogUtils.debug4plugin("zip file folder {} to {}", zipFileFolder, encodeZipFile.getAbsolutePath());
bytes = CommonIOUtils.inputStream2Bytes(new FileInputStream(encodeZipFile));
} catch (Exception e) {
LogUtils.error(e.getMessage(), e);
} finally {
if (zipFile != null) {
zipFile.deleteOnExit();
}
if (encodeZipFile != null) {
encodeZipFile.deleteOnExit();
}
unzipFileFolder.deleteOnExit();
zipFileFolder.deleteOnExit();
zipFile.deleteOnExit();
}
return bytes;
}
@Override
public void write(int b) throws IOException {
if (closed) {
throw new IOException("Cannot write to a closed output stream");
}
crypt.write(b);
}
@Override
public void close() throws IOException {
if (!closed) {
byte[] bytes = crypt.toByteArray();
bytes = encrypt(bytes, false);
original.write(bytes);
original.flush();
original.close();
closed = true;
}
}
@Override
public void flush() throws IOException {
crypt.flush();
}
@Override
public void write(byte[] data) throws IOException {
write(data, 0, data.length);
}
@Override
public void write(byte[] data, int off, int len) throws IOException {
if (closed) {
throw new IOException("Cannot write to a closed output stream");
}
crypt.write(data, off, len);
}
@Override
public boolean isReady() {
return true;
}
@Override
public void setWriteListener(WriteListener listener) {
}
}

25
src/main/java/com/fr/plugin/xx/zyjn/decode/encode/EncryptResponse.java

@ -0,0 +1,25 @@
package com.fr.plugin.xx.zyjn.decode.encode;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.IOException;
/**
* @Author xx
* @Date 2022/3/3
* @Description
**/
public class EncryptResponse extends HttpServletResponseWrapper {
public EncryptResponse(HttpServletResponse response) {
super(response);
}
@Override
public ServletOutputStream getOutputStream()throws IOException {
ServletOutputStream original = super.getOutputStream();
return new EncryptOutputStream(original);
}
}

71
src/main/java/com/fr/plugin/xx/zyjn/decode/encode/bi/EncodeFilter.java

@ -0,0 +1,71 @@
package com.fr.plugin.xx.zyjn.decode.encode.bi;
import com.fr.decision.fun.impl.AbstractGlobalRequestFilterProvider;
import com.fr.decision.webservice.v10.config.ConfigService;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.xx.zyjn.decode.LogUtils;
import com.fr.plugin.xx.zyjn.decode.util.GZIPUtils;
import com.fr.stable.StringUtils;
import javax.servlet.FilterChain;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @Author xx
* @Date 2022/3/3
* @Description
**/
public class EncodeFilter extends AbstractGlobalRequestFilterProvider {
@Override
public String filterName() {
return "encode";
}
@Override
public String[] urlPatterns() {
String servletPathName = "decision";
try {
servletPathName = ConfigService.getInstance().getBasicParam().getServletPathName();
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
return new String[]{
"/" + servletPathName + "/v5/design/report/data/export",
"/" + servletPathName + "/v5/design/report/data/global/export/pdf",
"/" + servletPathName + "/v5/design/report/data/global/export/excel",
};
}
@Override
public void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain filterChain) {
try {
String method = req.getMethod();
if ("POST".equalsIgnoreCase(method)) {
String uri = req.getRequestURI();
String query = req.getQueryString();
LogUtils.debug4plugin("BI export url {}",uri + "?" + query);
ResponseWrapperImpl wrapper = new ResponseWrapperImpl(res);
filterChain.doFilter(req, wrapper);
FileUtil.handle(res.getOutputStream(), os -> {
byte[] bytes = wrapper.getDataStream();
if (StringUtils.contains(wrapper.getHeader("Content-Encoding"), "gzip")) {
FineLoggerFactory.getLogger().info("current url {} is gzip", getUrl(req));
bytes = GZIPUtils.decompress(bytes);
}
os.write(bytes);
os.flush();
}, req,res);
}
} catch (Exception e) {
LogUtils.error(e.getMessage(), e);
}
}
private String getUrl(HttpServletRequest req) {
String uri = req.getRequestURI();
String query = req.getQueryString();
return StringUtils.isNotBlank(query) ? uri + "?" + query : uri;
}
}

18
src/main/java/com/fr/plugin/xx/zyjn/decode/encode/bi/ExportFunc.java

@ -0,0 +1,18 @@
package com.fr.plugin.xx.zyjn.decode.encode.bi;
import java.io.OutputStream;
/**
* @author xx
* @date 2020/11/20
*/
@FunctionalInterface
public interface ExportFunc {
/**
* 写入到临时输出流
*
* @param os 临时输出流
* @return void
**/
void export(OutputStream os) throws Exception;
}

169
src/main/java/com/fr/plugin/xx/zyjn/decode/encode/bi/FileUtil.java

@ -0,0 +1,169 @@
package com.fr.plugin.xx.zyjn.decode.encode.bi;
import com.fr.general.CommonIOUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.xx.zyjn.decode.LogUtils;
import com.fr.plugin.xx.zyjn.decode.encode.EncryptOutputStream;
import com.fr.plugin.xx.zyjn.decode.util.GZIPUtils;
import com.fr.stable.StringUtils;
import com.fr.third.org.apache.commons.io.IOUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.Arrays;
import java.util.UUID;
/**
* @author xx
* @date 2020/11/20
*/
public class FileUtil {
/**
* 文件加密之后再写入指定的输出流
*
* @param file
* @param stream
* @return void
**/
public static void handle(File file, OutputStream stream, HttpServletRequest req, HttpServletResponse res) {
InputStream is = null;
try {
FileInputStream inputStream = new FileInputStream(file);
byte[] encodeFile = encodeFile(CommonIOUtils.inputStream2Bytes(inputStream), req);
is = new ByteArrayInputStream(encodeFile);
byte[] bytes = CommonIOUtils.inputStream2Bytes(is);
if (StringUtils.contains(res.getHeader("Content-Encoding"), "gzip")) {
bytes = GZIPUtils.compress(bytes);
}
IOUtils.copyLarge(new ByteArrayInputStream(bytes), stream);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
if (stream != null) {
try {
stream.flush();
} catch (IOException e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
}
}
private static byte[] encodeFile(byte[] file, HttpServletRequest req) {
try {
return EncryptOutputStream.encrypt(file,true);
} catch (Exception e) {
LogUtils.error(e.getMessage(), e);
}
return file;
}
/**
* 加密导出文件后写入原始输出流中
* 回调函数式处理
*
* @param outputStream 原始输出流
* @param func 临时输出流处理
* @return void
**/
public static void handle(OutputStream outputStream, ExportFunc func, HttpServletRequest req, HttpServletResponse res) {
File tempFile = null;
OutputStream os = null;
//写入到临时文件
try {
tempFile = FileUtil.createTempFile();
os = new FileOutputStream(tempFile);
//直接写到临时文件里边
func.export(os);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
} finally {
if (os != null) {
try {
os.close();
} catch (IOException e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
}
//处理临时文件,写到原始输出流
try {
handle(tempFile, outputStream, req,res);//临时加密后写到原始输出流中
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
} finally {
if (tempFile != null) {
deleteFile(tempFile);//最后删除临时文件
}
}
}
/**
* 创建临时文件
*
* @return java.io.File
**/
public static File createTempFile() throws IOException {
return File.createTempFile("tmp" + UUID.randomUUID().toString(), null);//创建一个临时文件
}
/**
* 删除文件
*
* @param file
* @return boolean
* @author Zhanying
**/
public static boolean deleteFile(File file) {
boolean flag = file.exists() && file.isFile() && file.delete();
// 如果文件路径所对应的文件存在,并且是一个文件,则直接删除
return flag;
}
private static byte[] ZIP_HEADER_1 = new byte[]{80, 75, 3, 4};
private static byte[] ZIP_HEADER_2 = new byte[]{80, 75, 5, 6};
public static boolean isArchiveFile(byte[] file) {
if (file == null) {
return false;
}
boolean isArchive = false;
InputStream input = null;
try {
input = new ByteArrayInputStream(file);
byte[] buffer = new byte[4];
int length = input.read(buffer, 0, 4);
if (length == 4) {
isArchive = (Arrays.equals(ZIP_HEADER_1, buffer)) || (Arrays.equals(ZIP_HEADER_2, buffer));
}
} catch (IOException e) {
LogUtils.error(e.getMessage(), e);
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
}
}
}
return isArchive;
}
public static File createTempFolder(String path) {
File file = new File(System.getProperty("java.io.tmpdir")+File.separator+path);
file.mkdir();
return file;
}
}

70
src/main/java/com/fr/plugin/xx/zyjn/decode/encode/bi/ResponseWrapperImpl.java

@ -0,0 +1,70 @@
package com.fr.plugin.xx.zyjn.decode.encode.bi;
import javax.servlet.ServletOutputStream;
import javax.servlet.WriteListener;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
/**
* @author xx
* @date 2020/11/20
*/
public class ResponseWrapperImpl extends HttpServletResponseWrapper {
ByteArrayOutputStream output;
FilterServletOutputStream filterOutput;
public ResponseWrapperImpl(HttpServletResponse response) {
super(response);
output = new ByteArrayOutputStream();
}
@Override
public ServletOutputStream getOutputStream() throws IOException {
if (filterOutput == null) {
filterOutput = new FilterServletOutputStream(output);
}
return filterOutput;
}
public byte[] getDataStream() {
return output.toByteArray();
}
class FilterServletOutputStream extends ServletOutputStream {
DataOutputStream output;
public FilterServletOutputStream(OutputStream output) {
this.output = new DataOutputStream(output);
}
@Override
public void write(int arg0) throws IOException {
output.write(arg0);
}
@Override
public void write(byte[] arg0, int arg1, int arg2) throws IOException {
output.write(arg0, arg1, arg2);
}
@Override
public void write(byte[] arg0) throws IOException {
output.write(arg0);
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setWriteListener(WriteListener writeListener) {
}
}
}

89
src/main/java/com/fr/plugin/xx/zyjn/decode/util/GZIPUtils.java

@ -0,0 +1,89 @@
package com.fr.plugin.xx.zyjn.decode.util;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
/**
* @Author xx
* @Date 2020/9/15
* @Description
**/
public class GZIPUtils {
/**
* 数据压缩传输
*
* @param is
* @param os
* @throws Exception
*/
public static void compressTransfe(byte[] bytes, OutputStream out) throws IOException {
GZIPOutputStream gos = null;
try {
gos = new GZIPOutputStream(out);
gos.write(bytes);
gos.finish();
gos.flush();
} finally{
if(gos != null){
gos.close();
}
}
}
/**
* 数据压缩
*
* @param is
* @param os
* @throws Exception
*/
public static byte[] compress(byte[] bytes) throws IOException {
ByteArrayOutputStream out = null;
GZIPOutputStream gos = null;
try {
out = new ByteArrayOutputStream();
gos = new GZIPOutputStream(out);
gos.write(bytes);
gos.finish();
gos.flush();
} finally{
if(gos != null){
gos.close();
}
if(out != null){
out.close();
}
}
return out.toByteArray();
}
/**
* 数据解压
*
* @param in
* @return
* @throws IOException
*/
public static byte[] decompress(byte[] bytes) throws IOException {
ByteArrayInputStream in = new ByteArrayInputStream(bytes);
GZIPInputStream gin = new GZIPInputStream(in);
ByteArrayOutputStream out = new ByteArrayOutputStream();
int count;
byte data[] = new byte[1024];
while ((count = gin.read(data, 0, 1024)) != -1) {
out.write(data, 0, count);
}
out.flush();
out.close();
gin.close();
return out.toByteArray();
}
}
Loading…
Cancel
Save