Browse Source

open

master
pioneer 2 years ago
commit
8b6f94daf7
  1. BIN
      .gradle/7.1.1/dependencies-accessors/dependencies-accessors.lock
  2. 0
      .gradle/7.1.1/dependencies-accessors/gc.properties
  3. BIN
      .gradle/7.1.1/fileChanges/last-build.bin
  4. BIN
      .gradle/7.1.1/fileHashes/fileHashes.lock
  5. 0
      .gradle/7.1.1/gc.properties
  6. BIN
      .gradle/buildOutputCleanup/buildOutputCleanup.lock
  7. 2
      .gradle/buildOutputCleanup/cache.properties
  8. BIN
      .gradle/checksums/checksums.lock
  9. 0
      .gradle/vcs-1/gc.properties
  10. 6
      README.md
  11. 122
      build.gradle
  12. 13
      encrypt.xml
  13. 25
      plugin.xml
  14. 21
      src/main/java/com/eco/plugin/wink/xdfileencrypt/config/InitializeMonitor.java
  15. 50
      src/main/java/com/eco/plugin/wink/xdfileencrypt/config/WinkSimpleConfig.java
  16. 114
      src/main/java/com/eco/plugin/wink/xdfileencrypt/filter/DecryptRequest.java
  17. 46
      src/main/java/com/eco/plugin/wink/xdfileencrypt/filter/DelegatingServletInputStream.java
  18. 126
      src/main/java/com/eco/plugin/wink/xdfileencrypt/filter/EncryptOutputStream.java
  19. 23
      src/main/java/com/eco/plugin/wink/xdfileencrypt/filter/EncryptResponse.java
  20. 180
      src/main/java/com/eco/plugin/wink/xdfileencrypt/filter/SSOFilter.java
  21. 10
      src/main/java/com/eco/plugin/wink/xdfileencrypt/localeFinder/locale.java
  22. 363
      src/main/java/com/eco/plugin/wink/xdfileencrypt/utils/FRUtils.java
  23. 102
      src/main/java/com/eco/plugin/wink/xdfileencrypt/utils/FileUtils.java
  24. 348
      src/main/java/com/eco/plugin/wink/xdfileencrypt/utils/HttpUtils.java
  25. 108
      src/main/java/com/eco/plugin/wink/xdfileencrypt/utils/ResponseUtils.java
  26. 49
      src/main/java/com/eco/plugin/wink/xdfileencrypt/utils/TypeDict.java
  27. 369
      src/main/java/com/eco/plugin/wink/xdfileencrypt/utils/Utils.java
  28. 21
      src/main/java/com/eco/plugin/xx/xdfileencrypt/config/InitializeMonitor.java
  29. 50
      src/main/java/com/eco/plugin/xx/xdfileencrypt/config/WinkSimpleConfig.java
  30. 114
      src/main/java/com/eco/plugin/xx/xdfileencrypt/filter/DecryptRequest.java
  31. 46
      src/main/java/com/eco/plugin/xx/xdfileencrypt/filter/DelegatingServletInputStream.java
  32. 126
      src/main/java/com/eco/plugin/xx/xdfileencrypt/filter/EncryptOutputStream.java
  33. 23
      src/main/java/com/eco/plugin/xx/xdfileencrypt/filter/EncryptResponse.java
  34. 180
      src/main/java/com/eco/plugin/xx/xdfileencrypt/filter/SSOFilter.java
  35. 10
      src/main/java/com/eco/plugin/xx/xdfileencrypt/localeFinder/locale.java
  36. 363
      src/main/java/com/eco/plugin/xx/xdfileencrypt/utils/FRUtils.java
  37. 102
      src/main/java/com/eco/plugin/xx/xdfileencrypt/utils/FileUtils.java
  38. 348
      src/main/java/com/eco/plugin/xx/xdfileencrypt/utils/HttpUtils.java
  39. 108
      src/main/java/com/eco/plugin/xx/xdfileencrypt/utils/ResponseUtils.java
  40. 0
      src/main/java/com/eco/plugin/xx/xdfileencrypt/utils/Test.java
  41. 49
      src/main/java/com/eco/plugin/xx/xdfileencrypt/utils/TypeDict.java
  42. 369
      src/main/java/com/eco/plugin/xx/xdfileencrypt/utils/Utils.java
  43. 10
      src/main/resources/com/eco/plugin/xx/xdfileencrypt/locale/locale.properties
  44. 10
      src/main/resources/com/eco/plugin/xx/xdfileencrypt/locale/locale_zh_CN.properties

BIN
.gradle/7.1.1/dependencies-accessors/dependencies-accessors.lock

Binary file not shown.

0
.gradle/7.1.1/dependencies-accessors/gc.properties

BIN
.gradle/7.1.1/fileChanges/last-build.bin

Binary file not shown.

BIN
.gradle/7.1.1/fileHashes/fileHashes.lock

Binary file not shown.

0
.gradle/7.1.1/gc.properties

BIN
.gradle/buildOutputCleanup/buildOutputCleanup.lock

Binary file not shown.

2
.gradle/buildOutputCleanup/cache.properties

@ -0,0 +1,2 @@
#Fri Mar 17 15:02:20 CST 2023
gradle.version=7.1.1

BIN
.gradle/checksums/checksums.lock

Binary file not shown.

0
.gradle/vcs-1/gc.properties

6
README.md

@ -0,0 +1,6 @@
# open-JSD-10438
JSD-10438 excel导出加密\
免责说明:该源码为第三方爱好者提供,不保证源码和方案的可靠性,也不提供任何形式的源码教学指导和协助!\
仅作为开发者学习参考使用!禁止用于任何商业用途!\
为保护开发者隐私,开发者信息已隐去!若原开发者希望公开自己的信息,可联系【pioneer】处理。

122
build.gradle

@ -0,0 +1,122 @@
apply plugin: 'java'
ext {
/**
* jar的路径
* 1.jar需要打包到zip中,lib根目录下
* 2.jar仅仅是编译时需要lib下子目录下即可
*/
libPath = "$projectDir/../webroot/WEB-INF/lib"
/**
* class进行加密保护
*/
guard = false
def pluginInfo = getPluginInfo()
pluginPre = "fine-plugin"
pluginName = pluginInfo.id
pluginVersion = pluginInfo.version
outputPath = "$projectDir/../webroot/WEB-INF/plugins/plugin-" + pluginName + "-1.0/classes"
}
group = 'com.fr.plugin'
version = '10.0'
sourceCompatibility = '8'
sourceSets {
main {
java.outputDir = file(outputPath)
output.resourcesDir = file(outputPath)
}
}
ant.importBuild("encrypt.xml")
//ant变量
ant.projectDir = projectDir
ant.references["compile.classpath"] = ant.path {
fileset(dir: libPath, includes: '**/*.jar')
fileset(dir: ".",includes:"**/*.jar" )
}
classes.dependsOn('clean')
task copyFiles(type: Copy,dependsOn: 'classes'){
from outputPath
into "$projectDir/classes"
}
task preJar(type:Copy,dependsOn: guard ? 'compile_encrypt_javas' : 'compile_plain_javas'){
from "$projectDir/classes"
into "$projectDir/transform-classes"
include "**/*.*"
}
jar.dependsOn("preJar")
task makeJar(type: Jar,dependsOn: preJar){
from fileTree(dir: "$projectDir/transform-classes")
baseName pluginPre
appendix pluginName
version pluginVersion
destinationDir = file("$buildDir/libs")
doLast(){
delete file("$projectDir/classes")
delete file("$projectDir/transform-classes")
}
}
task copyFile(type: Copy,dependsOn: ["makeJar"]){
from "$buildDir/libs"
from("$projectDir/lib") {
include "*.jar"
}
from "$projectDir/plugin.xml"
into file("$buildDir/temp/plugin")
}
task zip(type:Zip,dependsOn:["copyFile"]){
from "$buildDir/temp/plugin"
destinationDir file("$buildDir/install")
baseName pluginPre
appendix pluginName
version pluginVersion
}
//build时包含哪些文件,
processResources {
// exclude everything
// *.css没效果
// exclude '**/*.css'
// except this file
// include 'xx.xml'
}
/*读取plugin.xml中的version*/
def getPluginInfo(){
def xmlFile = file("plugin.xml")
if (!xmlFile.exists()) {
return ["id":"none", "version":"1.0.0"]
}
def plugin = new XmlParser().parse(xmlFile)
def version = plugin.version[0].text()
def id = plugin.id[0].text()
return ["id":id,"version":version]
}
repositories {
mavenLocal()
maven {
url = uri('http://mvn.finedevelop.com/repository/maven-public/')
}
}
dependencies {
//使jar
implementation fileTree(dir: 'lib', include: ['**/*.jar'])
implementation fileTree(dir: libPath, include: ['**/*.jar'])
}

13
encrypt.xml

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project>
<target name="compile_encrypt_javas" depends="copyFiles">
<echo message="加密文件"/>
<echo message="${projectDir}"/>
<taskdef name="pretreatment" classname="com.fr.plugin.pack.PluginPretreatmentTask">
<classpath refid="compile.classpath"/>
</taskdef>
<pretreatment baseDir="${projectDir}"/>
</target>
<target name="compile_plain_javas" depends="copyFiles">
</target>
</project>

25
plugin.xml

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?><plugin>
<id>com.eco.plugin.xx.xdfileencrypt</id>
<name><![CDATA[导入导出加解密_EK]]></name>
<active>yes</active>
<version>1.1.1</version>
<env-version>10.0</env-version>
<jartime>2018-07-31</jartime>
<vendor>fr.open</vendor>
<description><![CDATA[导入导出加解密_EK]]></description>
<change-notes><![CDATA[
[2022-09-21] JSD-10438 初始化
]]></change-notes>
<main-package>com.eco.plugin.xx.xdfileencrypt</main-package>
<lifecycle-monitor class="com.eco.plugin.xx.xdfileencrypt.config.InitializeMonitor"/>
<extra-decision>
<GlobalRequestFilterProvider class="com.eco.plugin.xx.xdfileencrypt.filter.SSOFilter"/>
</extra-decision>
<extra-core>
<LocaleFinder class="com.eco.plugin.xx.xdfileencrypt.localeFinder.locale"/>
</extra-core>
<function-recorder class="com.eco.plugin.xx.xdfileencrypt.config.xxSimpleConfig"/>
</plugin>

21
src/main/java/com/eco/plugin/wink/xdfileencrypt/config/InitializeMonitor.java

@ -0,0 +1,21 @@
package com.eco.plugin.xx.xdfileencrypt.config;
import com.fr.plugin.context.PluginContext;
import com.fr.plugin.observer.inner.AbstractPluginLifecycleMonitor;
/**
* @author xx
* @version 10.0
* Created by xx on 2021-12-03
*/
public class InitializeMonitor extends AbstractPluginLifecycleMonitor {
@Override
public void afterRun(PluginContext pluginContext) {
xxSimpleConfig.getInstance();
}
@Override
public void beforeStop(PluginContext pluginContext) {
}
}

50
src/main/java/com/eco/plugin/wink/xdfileencrypt/config/WinkSimpleConfig.java

@ -0,0 +1,50 @@
package com.eco.plugin.xx.xdfileencrypt.config;
import com.fr.config.*;
import com.fr.config.holder.Conf;
import com.fr.config.holder.factory.Holders;
import com.fr.intelli.record.Focus;
import com.fr.intelli.record.Original;
import com.fr.record.analyzer.EnableMetrics;
@Visualization(category = "Plugin-Config-Title")
@EnableMetrics
public class xxSimpleConfig extends DefaultConfiguration {
private static volatile xxSimpleConfig config = null;
@Focus(id="com.eco.plugin.xx.xdfileencrypt.config", text = "Plugin-Config-Title", source = Original.PLUGIN)
public static xxSimpleConfig getInstance() {
if (config == null) {
config = ConfigContext.getConfigInstance(xxSimpleConfig.class);
}
return config;
}
@Identifier(value = "size", name = "Plugin-Config-Size", description = "Plugin-Config-Size", status = Status.SHOW)
private Conf<String> size = Holders.simple("");
public String getSize() {
return size.get();
}
public void setSize(String url) {
this.size.set(url);
}
@Override
public Object clone() throws CloneNotSupportedException {
xxSimpleConfig cloned = (xxSimpleConfig) super.clone();
// cloned.text = (Conf<String>) text.clone();
// cloned.count = (Conf<Integer>) count.clone();
// cloned.price = (Conf<Double>) price.clone();
// cloned.time = (Conf<Long>) time.clone();
// cloned.student = (Conf<Boolean>) student.clone();
return cloned;
}
}

114
src/main/java/com/eco/plugin/wink/xdfileencrypt/filter/DecryptRequest.java

@ -0,0 +1,114 @@
package com.eco.plugin.xx.xdfileencrypt.filter;
import com.eco.plugin.xx.xdfileencrypt.utils.FileUtils;
import com.eco.plugin.xx.xdfileencrypt.utils.HttpUtils;
import com.fr.base.core.IgnoreBytesInputStream;
import com.fr.base.core.ParseResult;
import com.fr.base.core.PostParseUtils;
import com.fr.cache.Attachment;
import com.fr.cache.type.AttachmentScope;
import com.fr.general.IOUtils;
import com.fr.stable.CodeUtils;
import com.fr.third.org.apache.commons.fileupload.FileItem;
import com.fr.third.org.apache.commons.fileupload.FileItemFactory;
import com.fr.third.org.apache.commons.fileupload.disk.DiskFileItemFactory;
import com.fr.third.org.apache.commons.fileupload.servlet.ServletFileUpload;
import com.fr.web.AttachmentHelper;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;
import java.io.ByteArrayOutputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
/**
* @author 秃破天际
* @version 10.0
* Created by 秃破天际 on 2021/7/15
**/
public class DecryptRequest extends HttpServletRequestWrapper {
// private static final String directory = "E:\\temp\\";
// private static final String directory2 = "E:\\temp\\temp2\\";
private byte[] data;
public DecryptRequest(HttpServletRequest request,String filename) {
super(request);
init(filename);
}
private void init(String filename) {
try {
getFileData((HttpServletRequest) getRequest());
data = IOUtils.inputStream2Bytes(getRequest().getInputStream());
// FileUtils.writeBytesToFile(data,directory2+"a.txt");
} catch (IOException e) {
data = new byte[0];
}
}
private static void getFileData(HttpServletRequest req){
if(ServletFileUpload.isMultipartContent(req)){
FileItemFactory fileItemFactory =new DiskFileItemFactory();
ServletFileUpload servletFileUpload =new ServletFileUpload(fileItemFactory);
servletFileUpload.setHeaderEncoding("utf-8");
servletFileUpload.setFileSizeMax(1024*1024*100);
try {
List<FileItem> list = servletFileUpload.parseRequest(req);
for (FileItem fileItem : list) {
if(fileItem.isFormField()){
String id = fileItem.getString("UTF-8");
}else {
String fileItemName = fileItem.getName();
String subname = fileItemName.substring(fileItemName.lastIndexOf("."), fileItemName.length());
String filename2 = java.util.UUID.randomUUID() + subname;
String realPath = req.getServletContext().getRealPath("work");
File file = new File(realPath + "/" + filename2);
fileItem.write(file);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
@Override
public BufferedReader getReader() {
return new BufferedReader(new InputStreamReader(getInputStream()));
}
@Override
public ServletInputStream getInputStream() {
final ByteArrayInputStream bais = new ByteArrayInputStream(data);
return new ServletInputStream() {
@Override
public int read() {
return bais.read();
}
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener readListener) {
}
};
}
}

46
src/main/java/com/eco/plugin/wink/xdfileencrypt/filter/DelegatingServletInputStream.java

@ -0,0 +1,46 @@
package com.eco.plugin.xx.xdfileencrypt.filter;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* @author 秃破天际
* @version 10.0
* Created by 秃破天际 on 2021/7/15
**/
public class DelegatingServletInputStream extends ServletInputStream {
private final InputStream sourceStream;
public DelegatingServletInputStream(InputStream stream) {
this.sourceStream = stream;
}
public final InputStream getSourceStream() {
return this.sourceStream;
}
@Override
public int read() throws IOException {
return this.sourceStream.read();
}
@Override
public void close() throws IOException {
super.close();
this.sourceStream.close();
}
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener listener) { }
}

126
src/main/java/com/eco/plugin/wink/xdfileencrypt/filter/EncryptOutputStream.java

@ -0,0 +1,126 @@
package com.eco.plugin.xx.xdfileencrypt.filter;
import com.eco.plugin.xx.xdfileencrypt.config.xxSimpleConfig;
import com.eco.plugin.xx.xdfileencrypt.utils.FileUtils;
import com.eco.plugin.xx.xdfileencrypt.utils.HttpUtils;
import com.eco.plugin.xx.xdfileencrypt.utils.Utils;
import com.fr.json.JSONObject;
import com.fr.record.analyzer.EnableMetrics;
import javax.servlet.ServletOutputStream;
import javax.servlet.WriteListener;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.UUID;
@EnableMetrics
public class EncryptOutputStream extends ServletOutputStream {
// private static final String directory = "E:\\temp\\";
// private static final String directory = "/opt/tomcat/temp/";
private static final String directory = "/usr/fine/temp";
private OutputStream original = null;
private boolean closed = false;
private ByteArrayOutputStream crypt = new ByteArrayOutputStream();
public EncryptOutputStream(OutputStream original){
this.original = original;
}
/**
* 实际加密的代码就在这里实现了
* @param bytes
* @return
*/
private byte[] encrypt(byte[] bytes) throws IOException {
String filename = UUID.randomUUID().toString()+Utils.getFileSuffix(bytes);
String originFilePath =directory+filename;
FileUtils.writeBytesToFile(bytes,originFilePath);
File originFile = new File(originFilePath);
String fileSize = xxSimpleConfig.getInstance().getSize();
if(Utils.isNotNullStr(fileSize)){
long size = Long.parseLong(fileSize);
long fileSizeReal = originFile.length()/1024/1024;
if(fileSizeReal > size){
throw new IOException("导出文件超出文件大小设置!");
}
}
String result = HttpUtils.HttpPostJson("http://localhost:8090/encrypt?fileName="+filename,"",null);
JSONObject jsonObject = new JSONObject(result);
String filePath = jsonObject.getString("filePath");
byte[] encryptFile = FileUtils.readBytesFromFile(filePath);
while (validateFile(bytes,encryptFile)){
encryptFile = FileUtils.readBytesFromFile(filePath);
}
byte[] resultByte = encryptFile.clone();
if(originFile.exists() && originFile.isFile()){
originFile.delete();
}
File targetFile = new File(filePath);
if(targetFile.exists() && targetFile.isFile()){
targetFile.delete();
}
return resultByte;
}
private boolean validateFile(byte[] bytes, byte[] encryptFile) {
return bytes[0] == encryptFile[0] && bytes[bytes.length-1] == encryptFile[encryptFile.length-1];
}
@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);
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) {
}
}

23
src/main/java/com/eco/plugin/wink/xdfileencrypt/filter/EncryptResponse.java

@ -0,0 +1,23 @@
package com.eco.plugin.xx.xdfileencrypt.filter;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.IOException;
/**
* @author 秃破天际
* @version 10.0
* Created by 秃破天际 on 2021/7/15
**/
public class EncryptResponse extends HttpServletResponseWrapper {
public EncryptResponse(HttpServletResponse response) {
super(response);
}
public ServletOutputStream getOutputStream()throws IOException {
ServletOutputStream original = super.getOutputStream();
return new EncryptOutputStream(original);
}
}

180
src/main/java/com/eco/plugin/wink/xdfileencrypt/filter/SSOFilter.java

@ -0,0 +1,180 @@
package com.eco.plugin.xx.xdfileencrypt.filter;
import com.eco.plugin.xx.xdfileencrypt.utils.FRUtils;
import com.eco.plugin.xx.xdfileencrypt.utils.FileUtils;
import com.eco.plugin.xx.xdfileencrypt.utils.HttpUtils;
import com.fr.base.core.IgnoreBytesInputStream;
import com.fr.base.core.ParseResult;
import com.fr.base.core.PostParseUtils;
import com.fr.cache.Attachment;
import com.fr.cache.AttachmentFileBase;
import com.fr.cache.AttachmentSource;
import com.fr.cache.factory.AttachmentFileManager;
import com.fr.cache.type.AttachmentScope;
import com.fr.decision.fun.impl.AbstractGlobalRequestFilterProvider;
import com.fr.decision.record.OperateMessage;
import com.fr.decision.webservice.utils.CharLimitType;
import com.fr.decision.webservice.utils.WebServiceUtils;
import com.fr.decision.webservice.v10.security.SecurityService;
import com.fr.general.CommonIOUtils;
import com.fr.general.ComparatorUtils;
import com.fr.intelli.record.MetricRegistry;
import com.fr.plugin.transform.FunctionRecorder;
import com.fr.record.analyzer.EnableMetrics;
import com.fr.security.WebSecurityConfig;
import com.fr.stable.CodeUtils;
import com.fr.third.org.apache.commons.io.FilenameUtils;
import com.fr.third.org.apache.http.entity.ContentType;
import com.fr.web.AttachmentHelper;
import com.fr.web.utils.WebUtils;
import javax.servlet.FilterChain;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.URLEncoder;
import java.util.UUID;
@EnableMetrics
@FunctionRecorder
public class SSOFilter 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 directory = "/opt/tomcat/temp/";
// private static final String directory = "E:\\temp\\";
private static final String directory = "/usr/fine/temp";
@Override
public String filterName() {
return "xdfileencryptFilter";
}
@Override
public String[] urlPatterns() {
return new String[]{"/*"};
}
@Override
public void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain chain ){
String url = FRUtils.getAllUrl(req);
if(url.contains("global/export")){
res = new EncryptResponse( res );
}
if(url.contains("attach/upload")){
String filename = req.getParameter("filename");
if(filename.contains(".xls") || filename.contains(".xlsx") || filename.contains(".csv")){
try {
int width = Integer.valueOf(req.getParameter("width"));
int height = Integer.valueOf(req.getParameter("height"));
uploadAttach(req,res,width,height,filename,false);
} catch (Exception e) {
FRUtils.FRLogInfo("上传文件失败:"+filename);
}
return ;
}
}
release(req,res,chain);
}
private static void uploadAttach(HttpServletRequest req, HttpServletResponse res, int width, int height, String filename, boolean isHolder) throws Exception {
SecurityService.checkXss(filename);
if (!filename.startsWith(" ") && !WebServiceUtils.containIllegalChars(CharLimitType.UPLOAD_FILE_NAME_LIMIT, filename)) {
ServletInputStream is = req.getInputStream();
ParseResult fileheader = PostParseUtils.parse(is, req.getCharacterEncoding());
/**
* 文件落盘
*/
String filenameNew = directory+"jm"+ UUID.randomUUID().toString()+ filename;
IgnoreBytesInputStream ignoreBytesInputStream = new IgnoreBytesInputStream(is, concat(concat(NEW_LINE_BYTES, fileheader.getBoundary().getBytes()), BOUNDARY_END));
FileUtils.inputstreamToFile(ignoreBytesInputStream,filenameNew);
/**
* 获取新文件inputStream
*/
byte[] decryptFileByte = HttpUtils.getFileByte("http://localhost:8090/decrypt?fileName="+URLEncoder.encode(filenameNew));
InputStream inputStream = new ByteArrayInputStream(decryptFileByte);
IgnoreBytesInputStream ignoreBytesInputStream2 = new IgnoreBytesInputStream(inputStream, concat(concat(NEW_LINE_BYTES, fileheader.getBoundary().getBytes()), BOUNDARY_END));
String fileType = fileheader.getContentType().indexOf("image") > 0 ? "image" : "other";
Attachment attachment = addAttachment(fileType, CodeUtils.cjkDecode(filename), ignoreBytesInputStream2, width, height, isHolder ? AttachmentScope.HOLDER : AttachmentScope.DEFAULT);
if (WebSecurityConfig.getInstance().isFileVerificationEnabled()) {
checkFile(fileType, attachment, filename);
}
MetricRegistry.getMetric().submit(OperateMessage.build("Dec-Module-Attachment", "Dec-Attachment_Upload", filename, "Dec-Log_Add"));
res.setContentType(ContentType.APPLICATION_JSON.getMimeType());
PrintWriter var12 = WebUtils.createPrintWriter(res);
var12.print(attachment.toConfig());
var12.flush();
var12.close();
} else {
throw new Exception("Dec-Data_Set_File_Name_Error");
}
}
/**
* 添加附件
* @param fileType 附件类型 image or other
* @param filename
* @param is
* @param width
* @param height
* @param scope
* @return
*/
public static Attachment addAttachment(String fileType, String filename, InputStream is, int width, int height, AttachmentScope scope) {
AttachmentFileBase fileBase = AttachmentFileManager.getManager().createFile((String)null, is, scope);
Attachment attachment = new Attachment(fileBase.getFileName(), fileType, filename, fileBase, width, height, scope);
AttachmentSource.putAttachment(fileBase.getFileName(), attachment);
return attachment;
}
private static byte[] concat(byte[] var1, byte[] var2) {
byte[] var3 = new byte[var1.length + var2.length];
System.arraycopy(var1, 0, var3, 0, var1.length);
System.arraycopy(var2, 0, var3, var1.length, var2.length);
return var3;
}
private static void checkFile(String var1, Attachment var2, String var3) throws Exception {
InputStream var4 = var2.getInputStream();
if (ComparatorUtils.equals(var1, "image") && var4.available() > 20971520) {
AttachmentHelper.removeAttachment(var2.getID());
throw new Exception("Dec-File_Too_Large_Error");
} else {
try {
boolean var5 = WebSecurityConfig.getInstance().getFileInspector().checkFileType(var4, FilenameUtils.getExtension(var3));
if (!var5) {
AttachmentHelper.removeAttachment(var2.getID());
throw new Exception("Dec-Invalid_file_Error");
}
} finally {
CommonIOUtils.close(var4);
}
}
}
//放行拦截器
private void release(HttpServletRequest req, HttpServletResponse res, FilterChain chain) {
try{
chain.doFilter(req,res);
}catch (Exception e){
}
}
}

10
src/main/java/com/eco/plugin/wink/xdfileencrypt/localeFinder/locale.java

@ -0,0 +1,10 @@
package com.eco.plugin.xx.xdfileencrypt.localeFinder;
import com.fr.stable.fun.impl.AbstractLocaleFinder;
public class locale extends AbstractLocaleFinder{
@Override
public String find() {
return "com/eco/plugin/xx/xdfileencrypt/locale/locale";
}
}

363
src/main/java/com/eco/plugin/wink/xdfileencrypt/utils/FRUtils.java

@ -0,0 +1,363 @@
package com.eco.plugin.xx.xdfileencrypt.utils;
import com.fr.base.ServerConfig;
import com.fr.base.TableData;
import com.fr.base.TemplateUtils;
import com.fr.decision.authority.AuthorityContext;
import com.fr.decision.authority.base.constant.type.operation.ManualOperationType;
import com.fr.decision.authority.data.User;
import com.fr.decision.base.util.UUIDUtil;
import com.fr.decision.privilege.TransmissionTool;
import com.fr.decision.privilege.encrpt.PasswordValidator;
import com.fr.decision.webservice.bean.authentication.OriginUrlResponseBean;
import com.fr.decision.webservice.interceptor.handler.ReportTemplateRequestChecker;
import com.fr.decision.webservice.login.LogInOutResultInfo;
import com.fr.decision.webservice.utils.DecisionServiceConstants;
import com.fr.decision.webservice.utils.DecisionStatusService;
import com.fr.decision.webservice.utils.UserSourceFactory;
import com.fr.decision.webservice.v10.login.LoginService;
import com.fr.decision.webservice.v10.login.event.LogInOutEvent;
import com.fr.decision.webservice.v10.user.UserService;
import com.fr.event.EventDispatcher;
import com.fr.file.TableDataConfig;
import com.fr.general.data.DataModel;
import com.fr.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import com.fr.script.Calculator;
import com.fr.stable.StringUtils;
import com.fr.stable.query.QueryFactory;
import com.fr.stable.query.restriction.RestrictionFactory;
import com.fr.third.springframework.web.method.HandlerMethod;
import com.fr.web.controller.ReportRequestService;
import com.fr.web.utils.WebUtils;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.List;
public class FRUtils {
/**
* 判断用户是否存在
* @param userName
* @return
*/
public static boolean isUserExist(String userName){
if (StringUtils.isEmpty(userName)) {
return false;
} else {
try {
List userList = AuthorityContext.getInstance().getUserController().find(QueryFactory.create().addRestriction(RestrictionFactory.eq("userName", userName)));
return userList != null && !userList.isEmpty();
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage());
return false;
}
}
}
/**
* 判断是否登录FR
* @param req
* @return
*/
public static boolean isLogin(HttpServletRequest req){
return LoginService.getInstance().isLogged(req);
}
/**
* 帆软登录
* @param httpServletRequest
* @param httpServletResponse
* @param userName
* @param url
*/
public static void login(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse,String userName,String url){
FineLoggerFactory.getLogger().info("FRLOG:用户名:"+userName+";跳转链接:"+url);
//判断用户名是否为空
if(!Utils.isNullStr(userName)){
if(isUserExist(userName)){
try {
LoginService.getInstance().login(httpServletRequest, httpServletResponse, userName);
EventDispatcher.fire(LogInOutEvent.LOGIN,new LogInOutResultInfo(httpServletRequest,httpServletResponse,userName,true));
FineLoggerFactory.getLogger().info("FRLOG:登陆成功!");
if(!Utils.isNullStr(url)){
httpServletResponse.sendRedirect(url);
}
} catch (Exception e) {
ResponseUtils.failedResponse(httpServletResponse,"登录异常,请联系管理员!");
FineLoggerFactory.getLogger().info("FRLOGException:"+e.getMessage());
}
}else{
ResponseUtils.failedResponse(httpServletResponse,"用户在报表系统中不存在!");
}
}else{
ResponseUtils.failedResponse(httpServletResponse,"用户名不能为空!");
}
}
/**
* 帆软登录
* @param httpServletRequest
* @param httpServletResponse
* @param token
* @param url
*/
public static void loginByToken(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse,String token,String url){
FineLoggerFactory.getLogger().info("FRLOG:token:"+token+";跳转链接:"+url);
//判断用户名是否为空
if(!Utils.isNullStr(token)){
writeToken2Cookie(httpServletResponse,token,-1);
HttpSession session = httpServletRequest.getSession(true);
httpServletRequest.setAttribute(DecisionServiceConstants.FINE_AUTH_TOKEN_NAME,token);
session.setAttribute(DecisionServiceConstants.FINE_AUTH_TOKEN_NAME, token);
if(!Utils.isNullStr(url)){
try {
httpServletResponse.sendRedirect(url);
} catch (IOException e) {
ResponseUtils.failedResponse(httpServletResponse,"跳转异常!");
}
}
}else{
ResponseUtils.failedResponse(httpServletResponse,"token不能为空!");
}
}
/**
* 产品原始登录方法
* @param req
* @param res
* @param username
* @return
*/
public static JSONObject originLogin(HttpServletRequest req,HttpServletResponse res,String username){
// String password = param.getString("password");
// password = decryptFRPsd(password);
FRUtils.FRLogInfo("originLogin:"+username);
if(isUserExist(username)){
try {
String token = LoginService.getInstance().login(req, res, username);
JSONObject result = new JSONObject();
result.put("username",username);
result.put("validity",-1);
result.put("accessToken",token);
result.put("username",username);
result.put("url","/webroot/decision");
JSONObject originUrlResponse = new JSONObject();
originUrlResponse.put("originUrl","/webroot/decision");
originUrlResponse.put("method","GET");
originUrlResponse.put("parameters",new JSONObject());
result.put("originUrlResponse",originUrlResponse);
return new JSONObject().put("data",result);
} catch (Exception e) {
ResponseUtils.failedResponse(res,"登录异常,请联系管理员!");
}
}else{
ResponseUtils.failedResponse(res,"用户在报表系统中不存在!");
}
return new JSONObject();
}
/**
* 获取token
* @param httpServletRequest
* @param httpServletResponse
* @param username
* @return
*/
public static String getToken(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse,String username){
String token = "";
try {
token = LoginService.getInstance().login(httpServletRequest, httpServletResponse, username);
} catch (Exception e) {
FineLoggerFactory.getLogger().info("FRLOG:获取token失败"+e.getMessage());
}
return token;
}
private static void writeToken2Cookie(HttpServletResponse req, String token, int num) {
try {
if (StringUtils.isNotEmpty(token)) {
Cookie cookie = new Cookie("fine_auth_token", token);
long maxAge = num == -2 ? 1209600000L : (long)num;
cookie.setMaxAge((int)maxAge);
cookie.setPath(ServerConfig.getInstance().getCookiePath());
req.addCookie(cookie);
Cookie rememberCookie = new Cookie("fine_remember_login", String.valueOf(num == -2 ? -2 : -1));
rememberCookie.setMaxAge((int)maxAge);
rememberCookie.setPath(ServerConfig.getInstance().getCookiePath());
req.addCookie(rememberCookie);
} else {
FineLoggerFactory.getLogger().error("empty token cannot save.");
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
/**
* 后台登出
* @param httpServletRequest
* @param httpServletResponse
*/
public static void logoutByToken(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse,String token)
{
httpServletRequest.setAttribute("fine_auth_token",token);
logout(httpServletRequest,httpServletResponse);
}
/**
*
* @param httpServletRequest
* @param httpServletResponse
*/
public static void logout(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse)
{
if(!isLogin(httpServletRequest)){
return ;
}
try {
LoginService.getInstance().logout(httpServletRequest,httpServletResponse);
} catch (Exception e) {
ResponseUtils.failedResponse(httpServletResponse,"登出异常,请联系管理员!");
FineLoggerFactory.getLogger().info("FRLOGException:"+e.getMessage());
}
}
/**
* 打印FR日志
* @param message
*/
public static void FRLogInfo(String message){
FineLoggerFactory.getLogger().info("FRLOG:"+message);
}
/**
* 打印FR日志-error
* @param message
*/
public static void FRLogError(String message){
FineLoggerFactory.getLogger().error("FRLOG:"+message);
}
/**
* 根据用户名获取用户信息
* @param userName
* @return
*/
public static User getFRUserByUserName(String userName){
try {
return UserService.getInstance().getUserByUserName(userName);
} catch (Exception e) {
FRLogInfo("获取用户信息异常:"+e.getMessage());
}
return null;
}
/**
* 解密FR密码
* @param password
* @return
*/
public static String decryptFRPsd(String password){
FRLogInfo("解密密码:"+password);
return TransmissionTool.decrypt(password);
}
/**
* 根据明文密码生成数据库中的密码用户密码校验用
* @return
*/
public static String getDBPsd(String username,String password){
PasswordValidator pv = UserSourceFactory.getInstance().getUserSource(ManualOperationType.KEY).getPasswordValidator();
String uuid = UUIDUtil.generate();
return pv.encode(username, password, uuid);
}
/**
* 获取带参数的访问链接
* @return
*/
public static String getAllUrl(HttpServletRequest httpServletRequest){
return WebUtils.getOriginalURL(httpServletRequest);
}
/**
* 根据originKey获取源链接
* @param req
* @return
* @throws Exception
*/
public static String getOriginUrl(HttpServletRequest req) throws Exception {
String origin = req.getParameter("origin");
if (StringUtils.isNotEmpty(origin)) {
OriginUrlResponseBean originUrlResponseBean = (OriginUrlResponseBean) DecisionStatusService.originUrlStatusService().get(origin);
DecisionStatusService.originUrlStatusService().delete(origin);
if (originUrlResponseBean != null) {
return originUrlResponseBean.getOriginUrl();
}
}
return new OriginUrlResponseBean(TemplateUtils.render("${fineServletURL}")).getOriginUrl();
}
/**
* 判断是否开启模板认证
* @param
* @return
* @throws Exception
*/
public static boolean isTempAuth(HttpServletRequest req,HttpServletResponse res) throws Exception {
ReportTemplateRequestChecker checker = new ReportTemplateRequestChecker();
HandlerMethod hm = new HandlerMethod(new ReportRequestService(),ReportRequestService.class.getMethod("preview", HttpServletRequest.class, HttpServletResponse.class, String.class));
return checker.checkRequest(req,res,hm);
}
/**
* 获取数据集数据
* @param serverDataSetName
* @return
*/
public static DataModel getTableData(String serverDataSetName){
TableData userInfo = TableDataConfig.getInstance().getTableData(serverDataSetName);
DataModel userInfoDM = userInfo.createDataModel(Calculator.createCalculator());
// userInfoDM.getRowCount();
// userInfoDM.getColumnIndex();
// userInfoDM.getValueAt()
return userInfoDM;
}
public static String getIndex(HttpServletRequest req){
String url = req.getScheme()+"://"+req.getServerName()+":"+String.valueOf(req.getServerPort())+req.getRequestURI();
return url;
}
/**
* 获取帆软域名
* @param req
* @return
*/
public static String getFRDomain(HttpServletRequest req){
return getAllUrl(req).split("/webroot")[0];
}
}

102
src/main/java/com/eco/plugin/wink/xdfileencrypt/utils/FileUtils.java

@ -0,0 +1,102 @@
package com.eco.plugin.xx.xdfileencrypt.utils;
import com.finebi.web.action.v5.api.BiApiAction;
import com.fr.base.core.IgnoreBytesInputStream;
import java.io.*;
public class FileUtils {
public static void writeBytesToFile(byte[] bFile, String fileDest) {
FileOutputStream fileOuputStream = null;
try {
fileOuputStream = new FileOutputStream(fileDest);
fileOuputStream.write(bFile);
} catch (IOException e) {
}finally {
if(fileOuputStream != null){
try {
fileOuputStream.flush();
fileOuputStream.close();
} catch (IOException e) {
}
}
}
}
public static void inputstreamToFile(IgnoreBytesInputStream inputStream, String filePath){
BufferedOutputStream bos = null;
BufferedInputStream bis = new BufferedInputStream(inputStream);
try {
bos = new BufferedOutputStream(new FileOutputStream(new File(filePath)));
int bytesRead = 0;
byte[] buffer = new byte[8192];
while ((bytesRead = bis.read(buffer, 0, 8192)) != -1) {
bos.write(buffer, 0, bytesRead);
}
} catch (Exception e) {
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
}
inputStream = null;
}
if (bos != null) {
try {
bos.close();
} catch (IOException e) {
}
bos = null;
}
if (bis != null) {
try {
bis.close();
} catch (IOException e) {
}
bis = null;
}
}
}
public static byte[] readBytesFromFile(String filePath) {
FileInputStream fileInputStream = null;
byte[] bytesArray = null;
try {
File file = new File(filePath);
bytesArray = new byte[(int) file.length()];
fileInputStream = new FileInputStream(file);
fileInputStream.read(bytesArray);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fileInputStream != null) {
try {
fileInputStream.close();
} catch (IOException e) {
}
}
}
return bytesArray;
}
}

348
src/main/java/com/eco/plugin/wink/xdfileencrypt/utils/HttpUtils.java

@ -0,0 +1,348 @@
package com.eco.plugin.xx.xdfileencrypt.utils;
import com.fr.log.FineLoggerFactory;
import com.fr.third.org.apache.http.HttpEntity;
import com.fr.third.org.apache.http.HttpResponse;
import com.fr.third.org.apache.http.HttpStatus;
import com.fr.third.org.apache.http.NameValuePair;
import com.fr.third.org.apache.http.client.CookieStore;
import com.fr.third.org.apache.http.client.entity.UrlEncodedFormEntity;
import com.fr.third.org.apache.http.client.methods.HttpGet;
import com.fr.third.org.apache.http.client.methods.HttpPost;
import com.fr.third.org.apache.http.conn.ssl.NoopHostnameVerifier;
import com.fr.third.org.apache.http.entity.StringEntity;
import com.fr.third.org.apache.http.impl.client.BasicCookieStore;
import com.fr.third.org.apache.http.impl.client.CloseableHttpClient;
import com.fr.third.org.apache.http.impl.client.HttpClients;
import com.fr.third.org.apache.http.impl.cookie.BasicClientCookie;
import com.fr.third.org.apache.http.message.BasicNameValuePair;
import com.fr.third.org.apache.http.ssl.SSLContexts;
import com.fr.third.org.apache.http.ssl.TrustStrategy;
import com.fr.third.org.apache.http.util.EntityUtils;
import javax.net.ssl.SSLContext;
import javax.servlet.http.Cookie;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class HttpUtils {
/**
* httpGet请求
* @param url
* @return
*/
public static String httpGet(String url,Cookie[] cookies,Map<String,String> header){
FineLoggerFactory.getLogger().info("FRLOG:HttpUtils.get--url:"+url);
//创建httpClient
CloseableHttpClient httpclient = createHttpClient(cookies);
HttpGet getMethod = new HttpGet(url);
if(header != null && header.size() > 0){
Set<String> keySet = header.keySet();
for(String key : keySet){
getMethod.setHeader(key,header.get(key));
}
}
try {
HttpResponse response = httpclient.execute(getMethod);
int status =response.getStatusLine().getStatusCode();
HttpEntity entity = response.getEntity();
String returnResult = EntityUtils.toString(entity, "utf-8");
FineLoggerFactory.getLogger().info("FRLOG:HttpUtils.get--status:"+status +";returnResult:"+returnResult);
httpclient.close();
if (status == HttpStatus.SC_OK) {
return returnResult;
}
} catch (Exception e) {
FineLoggerFactory.getLogger().info("FRLOG:HttpUtils.get--exception:"+e.getMessage());
}
try {
httpclient.close();
} catch (Exception e) {
FineLoggerFactory.getLogger().info("FRLOG:http关闭异常:"+e.getMessage());
}
return "";
}
public static byte[] httpPostByte(String url,byte[] param){
OutputStream out = null;
BufferedReader in = null;
String result = "";
try {
URL realUrl = new URL(url);
// 打开和URL之间的连接
URLConnection conn = realUrl.openConnection();
// 设置通用的请求属性
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("Content-Type", "text/plain");
conn.setRequestProperty("user-agent",
"PostmanRuntime/7.29.0");
// 发送POST请求必须设置如下两行
conn.setDoOutput(true);
conn.setDoInput(true);
/*-----------------------------------------*/
/*注意这里使用字节流*/
out = new BufferedOutputStream(conn.getOutputStream());
// 发送请求参数
out.write(param);
// flush输出流的缓冲
out.flush();
/*-----------------------------------------*/
// 定义BufferedReader输入流来读取URL的响应
byte[] file = toByteArray(conn.getInputStream());
return file;
} catch (Exception e) {
}
//使用finally块来关闭输出流、输入流
finally{
try{
if(out!=null){
out.close();
}
if(in!=null){
in.close();
}
}
catch(IOException ex){
}
}
return new byte[0];
}
/**
* HttpPost请求
* @param postMethod
* @return
*/
private static String HttpPost(HttpPost postMethod){
CloseableHttpClient httpclient = createHttpClient(null);
try {
HttpResponse response = httpclient.execute(postMethod);
int status = response.getStatusLine().getStatusCode();
HttpEntity entity = response.getEntity();
String returnResult = EntityUtils.toString(entity, "utf-8");
FineLoggerFactory.getLogger().info("FRLOG:HttpPost:status:"+status+"returnResult:"+returnResult);
httpclient.close();
if (status == HttpStatus.SC_OK) {
return returnResult;
}
} catch (Exception e) {
FineLoggerFactory.getLogger().info("FRLOG:HttpPost:exception:"+e.getMessage());
}
try {
httpclient.close();
} catch (Exception e) {
FineLoggerFactory.getLogger().info("FRLOG:http关闭异常:"+e.getMessage());
}
return "";
}
public static String HttpPostXML(String url, String xmlParam){
FineLoggerFactory.getLogger().info("FRLOG:HttpPostXML:url:"+url);
HttpPost postMethod = new HttpPost(url);
postMethod.setHeader("Content-type", "text/html");
HttpEntity entity = null;
try {
entity = new StringEntity(xmlParam);
} catch (UnsupportedEncodingException e) {
FineLoggerFactory.getLogger().info("FRLOG:HttpPostXML:参数异常:"+e.getMessage());
return "";
}
postMethod.setEntity(entity);
return HttpPost(postMethod);
}
public static String HttpPostText(String url, String xmlParam){
FineLoggerFactory.getLogger().info("FRLOG:HttpPostText:url:"+url);
HttpPost postMethod = new HttpPost(url);
postMethod.setHeader("Content-type", "text/plain");
HttpEntity entity = null;
try {
entity = new StringEntity(xmlParam);
} catch (UnsupportedEncodingException e) {
FineLoggerFactory.getLogger().info("FRLOG:HttpPostText:参数异常:"+e.getMessage());
return "";
}
postMethod.setEntity(entity);
return HttpPost(postMethod);
}
public static byte[] toByteArray(InputStream input) throws IOException {
ByteArrayOutputStream output = new ByteArrayOutputStream();
byte[] buffer = new byte[1024*4];
int n = 0;
while (-1 != (n = input.read(buffer))) {
output.write(buffer, 0, n);
}
return output.toByteArray();
}
public static byte[] getFileByte(String url){
FineLoggerFactory.getLogger().info("FRLOG:getFileByte:url:"+url);
HttpPost postMethod = new HttpPost(url);
postMethod.setHeader("Content-Type","application/json");
CloseableHttpClient httpclient = createHttpClient(null);
try {
HttpResponse response = httpclient.execute(postMethod);
HttpEntity entity = response.getEntity();
byte[] file = toByteArray(entity.getContent());
return file;
} catch (Exception e) {
FineLoggerFactory.getLogger().info("FRLOG:getFileByte:exception:"+e.getMessage());
}
try {
httpclient.close();
} catch (Exception e) {
FineLoggerFactory.getLogger().info("FRLOG:http关闭异常:"+e.getMessage());
}
return new byte[1];
}
public static String HttpPostJson(String url, String param,Map<String,String> header){
FineLoggerFactory.getLogger().info("FRLOG:getFileByte:url:"+url);
HttpPost postMethod = new HttpPost(url);
postMethod.setHeader("Content-Type","application/json");
if(header != null && header.size() > 0){
Set<String> keySet = header.keySet();
for(String key : keySet){
postMethod.setHeader(key,header.get(key));
}
}
if(!Utils.isNullStr(param)){
HttpEntity entity = null;
try {
entity = new StringEntity(param);
} catch (UnsupportedEncodingException e) {
FineLoggerFactory.getLogger().info("FRLOG:HttpPostJSON:参数异常:"+e.getMessage());
return "";
}
postMethod.setEntity(entity);
}
return HttpPost(postMethod);
}
public static String HttpPostForm(String url, Map<String,String> header,Map<String,String> param){
FineLoggerFactory.getLogger().info("FRLOG:HttpForm:url:"+url);
HttpPost postMethod = new HttpPost(url);
if(header != null && header.size() > 0){
Set<String> keySet = header.keySet();
for(String key : keySet){
postMethod.setHeader(key,header.get(key));
}
}
if(param != null && param.size() > 0){
List<NameValuePair> params = new ArrayList<NameValuePair>(param.size());
for(Map.Entry<String,String> map : param.entrySet()){
params.add(new BasicNameValuePair(map.getKey(), map.getValue()));
}
try {
postMethod.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
} catch (UnsupportedEncodingException e) {
FineLoggerFactory.getLogger().info("FRLOG:HttpForm:异常:"+e.getMessage());
return "";
}
}
return HttpPost(postMethod);
}
private static CloseableHttpClient createHttpClient(Cookie[] cookies){
SSLContext sslContext = null;
try {
sslContext = SSLContexts.custom().loadTrustMaterial(null, new TrustStrategy() {
@Override
public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
return true;
}
}).build();
} catch (Exception e) {
FRUtils.FRLogInfo("exception:"+e.getMessage());
}
CloseableHttpClient httpclient = null;
if(cookies != null && cookies.length > 0){
CookieStore cookieStore = cookieToCookieStore(cookies);
httpclient = HttpClients.custom().setSslcontext(sslContext).
setSSLHostnameVerifier(new NoopHostnameVerifier()).setDefaultCookieStore(cookieStore).build();
}
else{
httpclient = HttpClients.custom().setSslcontext(sslContext).
setSSLHostnameVerifier(new NoopHostnameVerifier()).build();
}
return httpclient;
}
/**
* cookies转cookieStore
* @param cookies
* @return
*/
public static CookieStore cookieToCookieStore(Cookie[] cookies){
CookieStore cookieStore = new BasicCookieStore();
if(cookies != null && cookies.length>0){
for(Cookie cookie : cookies){
BasicClientCookie cookie1 = new BasicClientCookie(cookie.getName(), cookie.getValue());
cookieStore.addCookie(cookie1);
}
}
return cookieStore;
}
}

108
src/main/java/com/eco/plugin/wink/xdfileencrypt/utils/ResponseUtils.java

@ -0,0 +1,108 @@
package com.eco.plugin.xx.xdfileencrypt.utils;
import com.fr.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import com.fr.web.utils.WebUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
public class ResponseUtils {
private static final int SUCCESS = 200;
private static final int FAILED = -1;
public static void successResponse(HttpServletResponse res, String body) {
response(res, body, SUCCESS);
}
public static void failedResponse(HttpServletResponse res, String body) {
response(res, body, FAILED);
}
private static void response(HttpServletResponse res, String body, int code) {
JSONObject object = new JSONObject();
PrintWriter pw;
try {
object.put("code", code);
object.put("data", body);
pw = WebUtils.createPrintWriter(res);
} catch (Exception e) {
FineLoggerFactory.getLogger().info(e.getMessage());
return;
}
res.setContentType("application/json;charset=utf-8");
String result = object.toString();
pw.println(result);
pw.flush();
pw.close();
}
public static void response(HttpServletResponse res,JSONObject json){
PrintWriter pw;
try {
pw = WebUtils.createPrintWriter(res);
} catch (Exception e) {
FineLoggerFactory.getLogger().info(e.getMessage());
return;
}
res.setContentType("application/json;charset=utf-8");
String result = json.toString();
pw.println(result);
pw.flush();
pw.close();
}
public static void responseText(HttpServletResponse res,String text){
PrintWriter pw;
try {
pw = WebUtils.createPrintWriter(res);
} catch (Exception e) {
FineLoggerFactory.getLogger().info(e.getMessage());
return;
}
res.setContentType("text/html;charset=utf-8");
pw.println(text);
pw.flush();
pw.close();
}
public static void responseXml(HttpServletResponse res,String xml){
PrintWriter pw;
try {
pw = WebUtils.createPrintWriter(res);
} catch (Exception e) {
FineLoggerFactory.getLogger().info(e.getMessage());
return;
}
res.setContentType("text/xml;charset=utf-8");
pw.println(xml);
pw.flush();
pw.close();
}
public static void setCSRFHeader(HttpServletResponse httpServletResponse){
httpServletResponse.setHeader("Access-Control-Allow-Origin", "*");
httpServletResponse.setHeader("Access-Control-Allow-Methods", "POST,GET,OPTIONS,DELETE,HEAD,PUT,PATCH");
httpServletResponse.setHeader("Access-Control-Max-Age", "36000");
httpServletResponse.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept,Authorization,authorization");
}
public static void responseJsonp(HttpServletRequest req, HttpServletResponse res, JSONObject json){
PrintWriter pw;
try {
pw = WebUtils.createPrintWriter(res);
} catch (Exception e) {
FineLoggerFactory.getLogger().info(e.getMessage());
return;
}
res.setContentType("text/javascript;charset=utf-8;charset=utf-8");
String result = json.toString();
String jsonp=req.getParameter("callback");
pw.println(jsonp+"("+result+")");
pw.flush();
pw.close();
}
}

49
src/main/java/com/eco/plugin/wink/xdfileencrypt/utils/TypeDict.java

@ -0,0 +1,49 @@
package com.eco.plugin.xx.xdfileencrypt.utils;
public class TypeDict {
/**
常用文件的文件头如下(以前六位为准)
JPEG (jpg)文件头FFD8FF
PNG (png)文件头89504E47
GIF (gif)文件头47494638
TIFF (tif)文件头49492A00
Windows Bitmap (bmp)文件头424D
CAD (dwg)文件头41433130
Adobe Photoshop (psd)文件头38425053
Rich Text Format (rtf)文件头7B5C727466
XML (xml)文件头3C3F786D6C
HTML (html)文件头68746D6C3E
Email [thorough only] (eml)文件头44656C69766572792D646174653A
Outlook Express (dbx)文件头CFAD12FEC5FD746F
Outlook (pst)文件头2142444E
MS Word/Excel (xls.or.doc)文件头D0CF11E0
MS Access (mdb)文件头5374616E64617264204A
WordPerfect (wpd)文件头FF575043
Postscript (eps.or.ps)文件头252150532D41646F6265
Adobe Acrobat (pdf)文件头255044462D312E
Quicken (qdf)文件头AC9EBD8F
Windows Password (pwl)文件头E3828596
ZIP Archive (zip)文件头504B0304
RAR Archive (rar)文件头52617221
Wave (wav)文件头57415645
AVI (avi)文件头41564920
Real Audio (ram)文件头2E7261FD
Real Media (rm)文件头2E524D46
MPEG (mpg)文件头000001BA
MPEG (mpg)文件头000001B3
Quicktime (mov)文件头6D6F6F76
Windows Media (asf)文件头3026B2758E66CF11
MIDI (mid)文件头4D546864
*/
public static String checkType(String fileheader) {
switch (fileheader) {
case "D0CF11": return ".xls";
case "255044": return ".pdf";
case "504B03": return ".xlsx";
case "EFBBBF": return ".csv";
default: return "0000";
}
}
}

369
src/main/java/com/eco/plugin/wink/xdfileencrypt/utils/Utils.java

@ -0,0 +1,369 @@
package com.eco.plugin.xx.xdfileencrypt.utils;
import com.fr.base.TemplateUtils;
import com.fr.data.NetworkHelper;
import com.fr.decision.webservice.v10.user.UserService;
import com.fr.io.utils.ResourceIOUtils;
import com.fr.json.JSONObject;
import com.fr.stable.CodeUtils;
import com.fr.stable.StringUtils;
import com.fr.third.org.apache.commons.codec.digest.DigestUtils;
import com.fr.web.utils.WebUtils;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Utils {
public static byte[] getByteHeader(byte[] bytes){
byte[] newByte = new byte[3];
for(int i=0;i<bytes.length;i++){
if(i < 3){
newByte[i] = bytes[i];
continue;
}
break;
}
return newByte;
}
public static String bytesToHexString(byte[] src) {
StringBuilder stringBuilder = new StringBuilder();
if (src == null || src.length <= 0) {
return null;
}
for (int i = 0; i < src.length; i++) {
int v = src[i] & 0xFF;
String hv = Integer.toHexString(v);
if (hv.length() < 2) {
stringBuilder.append(0);
}
stringBuilder.append(hv);
}
return stringBuilder.toString();
}
public static String getFileSuffix(byte[] bytes){
String byteHeader = bytesToHexString(getByteHeader(bytes));
byteHeader = byteHeader.toUpperCase();
String suffix = TypeDict.checkType(byteHeader);
FRUtils.FRLogInfo("suffix:"+suffix);
return suffix;
}
/**
* 判断字符串是否为空
* @param str
* @return true 空字符串 false 非空字符串
*/
public static boolean isNullStr(String str){
return !(str != null && !str.isEmpty() && !"null".equals(str));
}
/**
* 判断字符串是否非空
* @param str
* @return
*/
public static boolean isNotNullStr(String str){
return !isNullStr(str);
}
/**
* MD5加密
* @param str
* @return
*/
public static String getMd5Str(String str)
{
return DigestUtils.md5Hex(str);
}
/**
* 帆软shaEncode加密
*/
public static String shaEncode(String str){
return CodeUtils.sha256Encode(str);
}
/**
* 获取uuid
*/
public static String uuid(){
return UUID.randomUUID().toString();
}
/**
* 替换空字符串
* @param str
* @param replace
* @return
*/
public static String replaceNullStr(String str,String replace){
if(isNullStr(str)){
return replace;
}
return str;
}
/**
* 获取请求体
* @param req
* @return
*/
public static JSONObject getRequestBody(HttpServletRequest req){
StringBuffer sb = new StringBuffer();
String line = null;
try {
BufferedReader reader = req.getReader();
while ((line = reader.readLine()) != null)
sb.append(line);
} catch (Exception e) {
FRUtils.FRLogInfo("getRequestBody:exception:"+e.getMessage());
}
//将空格和换行符替换掉避免使用反序列化工具解析对象时失败
String jsonString = sb.toString().replaceAll("\\s","").replaceAll("\n","");
FRUtils.FRLogInfo("reqBody:"+jsonString);
JSONObject json = new JSONObject(jsonString);
return json;
}
/**
* 获取ip
* @return
*/
public static String getIp(HttpServletRequest req){
String realIp = req.getHeader("X-Real-IP");
String fw = req.getHeader("X-Forwarded-For");
if (StringUtils.isNotEmpty(fw) && !"unKnown".equalsIgnoreCase(fw)) {
int para3 = fw.indexOf(",");
return para3 != -1 ? fw.substring(0, para3) : fw;
} else {
fw = realIp;
if (StringUtils.isNotEmpty(realIp) && !"unKnown".equalsIgnoreCase(realIp)) {
return realIp;
} else {
if (StringUtils.isBlank(realIp) || "unknown".equalsIgnoreCase(realIp)) {
fw = req.getHeader("Proxy-Client-IP");
}
if (StringUtils.isBlank(fw) || "unknown".equalsIgnoreCase(fw)) {
fw = req.getHeader("WL-Proxy-Client-IP");
}
if (StringUtils.isBlank(fw) || "unknown".equalsIgnoreCase(fw)) {
fw = req.getHeader("HTTP_CLIENT_IP");
}
if (StringUtils.isBlank(fw) || "unknown".equalsIgnoreCase(fw)) {
fw = req.getHeader("HTTP_X_FORWARDED_FOR");
}
if (StringUtils.isBlank(fw) || "unknown".equalsIgnoreCase(fw)) {
fw = req.getRemoteAddr();
}
return fw;
}
}
}
/**
* 根据key获取cookie
* @param req
* @return
*/
public static String getCookieByKey(HttpServletRequest req,String key){
Cookie[] cookies = req.getCookies();
String cookie = "";
if(cookies == null || cookies.length <=0){
return "";
}
for(int i = 0; i < cookies.length; i++) {
Cookie item = cookies[i];
if (item.getName().equalsIgnoreCase(key)) {
cookie = item.getValue();
}
}
FRUtils.FRLogInfo("cookie:"+cookie);
return cookie;
}
/**
* 判断是否是手机端的链接
* @param req
* @return
*/
public static boolean isMobile(HttpServletRequest req) {
String[] mobileArray = {"iPhone", "iPad", "android", "windows phone", "xiaomi"};
String userAgent = req.getHeader("user-agent");
if (userAgent != null && userAgent.toUpperCase().contains("MOBILE")) {
for(String mobile : mobileArray) {
if(userAgent.toUpperCase().contains(mobile.toUpperCase())) {
return true;
}
}
}
return NetworkHelper.getDevice(req).isMobile();
}
/**
* 只编码中文
* @param url
* @return
*/
public static String encodeCH(String url ){
Matcher matcher = Pattern.compile("[\\u4e00-\\u9fa5]").matcher(url);
while(matcher.find()){
String chn = matcher.group();
url = url.replaceAll(chn, URLEncoder.encode(chn));
}
return url;
}
/**
* 获取web-inf文件夹下的文件
* filename /resources/ip4enc.properties
*/
public static InputStream getResourcesFile(String filename){
return ResourceIOUtils.read(filename);
}
/**
*
* @param res
* @param path /com/fr/plugin/loginAuth/html/getMac.html
* @param parameterMap
*/
public static void toErrorPage(HttpServletResponse res,String path,Map<String, String> parameterMap){
if(parameterMap == null){
parameterMap = new HashMap<String, String>();
}
try {
String macPage = TemplateUtils.renderTemplate(path, parameterMap);
WebUtils.printAsString(res, macPage);
}catch (Exception e){
FRUtils.FRLogError("跳转页面异常");
}
}
/**
* 判断是否是管理员
* @param username
* @return
*/
public static boolean isAdmin(String username) throws Exception{
return UserService.getInstance().isAdmin(UserService.getInstance().getUserByUserName(username).getId());
}
/**
* 去掉浏览器中的参数
* @param url
* @param param
* @return
*/
public static String removeParam(String url,String param){
if(!url.contains("?"+param) && !url.contains("&"+param)){
return url;
}
return url.substring(0,url.indexOf(url.contains("?"+param) ? "?"+param : "&"+param));
}
/**
* 获取跳转链接
* @param req
* @param param
* @return
*/
public static String getRedirectUrl(HttpServletRequest req,String param){
String url = FRUtils.getAllUrl(req);
if(isNotNullStr(param)){
url = removeParam(url,param);
}
url = encodeCH(url);
return url;
}
/**
* 去除空格换行
* @param str
* @return
*/
public static String trim(String str){
return str.trim().replaceAll("\n","").replaceAll("\r","");
}
/**
* list 转化为指定字符分割的字符串
* @param list
* @param list
* @return
*/
public static String listToStr(List<String> list, String split){
String result = "";
if(list == null || list.size() <= 0){
return result;
}
for(String str : list){
result+=","+str;
}
result = result.substring(1);
return result;
}
/**
* array 转化为指定字符分割的字符串
* @param list
* @param list
* @return
*/
public static String arrayToStr(String[] list, String split){
String result = "";
if(list == null ||list.length <= 0){
return result;
}
for(int i=0;i<list.length;i++){
String str = list[i];
result+=","+str;
}
result = result.substring(1);
return result;
}
}

21
src/main/java/com/eco/plugin/xx/xdfileencrypt/config/InitializeMonitor.java

@ -0,0 +1,21 @@
package com.eco.plugin.wink.xdfileencrypt.config;
import com.fr.plugin.context.PluginContext;
import com.fr.plugin.observer.inner.AbstractPluginLifecycleMonitor;
/**
* @author wink
* @version 10.0
* Created by wink on 2021-12-03
*/
public class InitializeMonitor extends AbstractPluginLifecycleMonitor {
@Override
public void afterRun(PluginContext pluginContext) {
WinkSimpleConfig.getInstance();
}
@Override
public void beforeStop(PluginContext pluginContext) {
}
}

50
src/main/java/com/eco/plugin/xx/xdfileencrypt/config/WinkSimpleConfig.java

@ -0,0 +1,50 @@
package com.eco.plugin.wink.xdfileencrypt.config;
import com.fr.config.*;
import com.fr.config.holder.Conf;
import com.fr.config.holder.factory.Holders;
import com.fr.intelli.record.Focus;
import com.fr.intelli.record.Original;
import com.fr.record.analyzer.EnableMetrics;
@Visualization(category = "Plugin-Config-Title")
@EnableMetrics
public class WinkSimpleConfig extends DefaultConfiguration {
private static volatile WinkSimpleConfig config = null;
@Focus(id="com.eco.plugin.wink.xdfileencrypt.config", text = "Plugin-Config-Title", source = Original.PLUGIN)
public static WinkSimpleConfig getInstance() {
if (config == null) {
config = ConfigContext.getConfigInstance(WinkSimpleConfig.class);
}
return config;
}
@Identifier(value = "size", name = "Plugin-Config-Size", description = "Plugin-Config-Size", status = Status.SHOW)
private Conf<String> size = Holders.simple("");
public String getSize() {
return size.get();
}
public void setSize(String url) {
this.size.set(url);
}
@Override
public Object clone() throws CloneNotSupportedException {
WinkSimpleConfig cloned = (WinkSimpleConfig) super.clone();
// cloned.text = (Conf<String>) text.clone();
// cloned.count = (Conf<Integer>) count.clone();
// cloned.price = (Conf<Double>) price.clone();
// cloned.time = (Conf<Long>) time.clone();
// cloned.student = (Conf<Boolean>) student.clone();
return cloned;
}
}

114
src/main/java/com/eco/plugin/xx/xdfileencrypt/filter/DecryptRequest.java

@ -0,0 +1,114 @@
package com.eco.plugin.wink.xdfileencrypt.filter;
import com.eco.plugin.wink.xdfileencrypt.utils.FileUtils;
import com.eco.plugin.wink.xdfileencrypt.utils.HttpUtils;
import com.fr.base.core.IgnoreBytesInputStream;
import com.fr.base.core.ParseResult;
import com.fr.base.core.PostParseUtils;
import com.fr.cache.Attachment;
import com.fr.cache.type.AttachmentScope;
import com.fr.general.IOUtils;
import com.fr.stable.CodeUtils;
import com.fr.third.org.apache.commons.fileupload.FileItem;
import com.fr.third.org.apache.commons.fileupload.FileItemFactory;
import com.fr.third.org.apache.commons.fileupload.disk.DiskFileItemFactory;
import com.fr.third.org.apache.commons.fileupload.servlet.ServletFileUpload;
import com.fr.web.AttachmentHelper;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;
import java.io.ByteArrayOutputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
/**
* @author 秃破天际
* @version 10.0
* Created by 秃破天际 on 2021/7/15
**/
public class DecryptRequest extends HttpServletRequestWrapper {
// private static final String directory = "E:\\temp\\";
// private static final String directory2 = "E:\\temp\\temp2\\";
private byte[] data;
public DecryptRequest(HttpServletRequest request,String filename) {
super(request);
init(filename);
}
private void init(String filename) {
try {
getFileData((HttpServletRequest) getRequest());
data = IOUtils.inputStream2Bytes(getRequest().getInputStream());
// FileUtils.writeBytesToFile(data,directory2+"a.txt");
} catch (IOException e) {
data = new byte[0];
}
}
private static void getFileData(HttpServletRequest req){
if(ServletFileUpload.isMultipartContent(req)){
FileItemFactory fileItemFactory =new DiskFileItemFactory();
ServletFileUpload servletFileUpload =new ServletFileUpload(fileItemFactory);
servletFileUpload.setHeaderEncoding("utf-8");
servletFileUpload.setFileSizeMax(1024*1024*100);
try {
List<FileItem> list = servletFileUpload.parseRequest(req);
for (FileItem fileItem : list) {
if(fileItem.isFormField()){
String id = fileItem.getString("UTF-8");
}else {
String fileItemName = fileItem.getName();
String subname = fileItemName.substring(fileItemName.lastIndexOf("."), fileItemName.length());
String filename2 = java.util.UUID.randomUUID() + subname;
String realPath = req.getServletContext().getRealPath("work");
File file = new File(realPath + "/" + filename2);
fileItem.write(file);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
@Override
public BufferedReader getReader() {
return new BufferedReader(new InputStreamReader(getInputStream()));
}
@Override
public ServletInputStream getInputStream() {
final ByteArrayInputStream bais = new ByteArrayInputStream(data);
return new ServletInputStream() {
@Override
public int read() {
return bais.read();
}
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener readListener) {
}
};
}
}

46
src/main/java/com/eco/plugin/xx/xdfileencrypt/filter/DelegatingServletInputStream.java

@ -0,0 +1,46 @@
package com.eco.plugin.wink.xdfileencrypt.filter;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* @author 秃破天际
* @version 10.0
* Created by 秃破天际 on 2021/7/15
**/
public class DelegatingServletInputStream extends ServletInputStream {
private final InputStream sourceStream;
public DelegatingServletInputStream(InputStream stream) {
this.sourceStream = stream;
}
public final InputStream getSourceStream() {
return this.sourceStream;
}
@Override
public int read() throws IOException {
return this.sourceStream.read();
}
@Override
public void close() throws IOException {
super.close();
this.sourceStream.close();
}
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener listener) { }
}

126
src/main/java/com/eco/plugin/xx/xdfileencrypt/filter/EncryptOutputStream.java

@ -0,0 +1,126 @@
package com.eco.plugin.wink.xdfileencrypt.filter;
import com.eco.plugin.wink.xdfileencrypt.config.WinkSimpleConfig;
import com.eco.plugin.wink.xdfileencrypt.utils.FileUtils;
import com.eco.plugin.wink.xdfileencrypt.utils.HttpUtils;
import com.eco.plugin.wink.xdfileencrypt.utils.Utils;
import com.fr.json.JSONObject;
import com.fr.record.analyzer.EnableMetrics;
import javax.servlet.ServletOutputStream;
import javax.servlet.WriteListener;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.UUID;
@EnableMetrics
public class EncryptOutputStream extends ServletOutputStream {
// private static final String directory = "E:\\temp\\";
// private static final String directory = "/opt/tomcat/temp/";
private static final String directory = "/usr/fine/temp";
private OutputStream original = null;
private boolean closed = false;
private ByteArrayOutputStream crypt = new ByteArrayOutputStream();
public EncryptOutputStream(OutputStream original){
this.original = original;
}
/**
* 实际加密的代码就在这里实现了
* @param bytes
* @return
*/
private byte[] encrypt(byte[] bytes) throws IOException {
String filename = UUID.randomUUID().toString()+Utils.getFileSuffix(bytes);
String originFilePath =directory+filename;
FileUtils.writeBytesToFile(bytes,originFilePath);
File originFile = new File(originFilePath);
String fileSize = WinkSimpleConfig.getInstance().getSize();
if(Utils.isNotNullStr(fileSize)){
long size = Long.parseLong(fileSize);
long fileSizeReal = originFile.length()/1024/1024;
if(fileSizeReal > size){
throw new IOException("导出文件超出文件大小设置!");
}
}
String result = HttpUtils.HttpPostJson("http://localhost:8090/encrypt?fileName="+filename,"",null);
JSONObject jsonObject = new JSONObject(result);
String filePath = jsonObject.getString("filePath");
byte[] encryptFile = FileUtils.readBytesFromFile(filePath);
while (validateFile(bytes,encryptFile)){
encryptFile = FileUtils.readBytesFromFile(filePath);
}
byte[] resultByte = encryptFile.clone();
if(originFile.exists() && originFile.isFile()){
originFile.delete();
}
File targetFile = new File(filePath);
if(targetFile.exists() && targetFile.isFile()){
targetFile.delete();
}
return resultByte;
}
private boolean validateFile(byte[] bytes, byte[] encryptFile) {
return bytes[0] == encryptFile[0] && bytes[bytes.length-1] == encryptFile[encryptFile.length-1];
}
@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);
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) {
}
}

23
src/main/java/com/eco/plugin/xx/xdfileencrypt/filter/EncryptResponse.java

@ -0,0 +1,23 @@
package com.eco.plugin.wink.xdfileencrypt.filter;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.IOException;
/**
* @author 秃破天际
* @version 10.0
* Created by 秃破天际 on 2021/7/15
**/
public class EncryptResponse extends HttpServletResponseWrapper {
public EncryptResponse(HttpServletResponse response) {
super(response);
}
public ServletOutputStream getOutputStream()throws IOException {
ServletOutputStream original = super.getOutputStream();
return new EncryptOutputStream(original);
}
}

180
src/main/java/com/eco/plugin/xx/xdfileencrypt/filter/SSOFilter.java

@ -0,0 +1,180 @@
package com.eco.plugin.wink.xdfileencrypt.filter;
import com.eco.plugin.wink.xdfileencrypt.utils.FRUtils;
import com.eco.plugin.wink.xdfileencrypt.utils.FileUtils;
import com.eco.plugin.wink.xdfileencrypt.utils.HttpUtils;
import com.fr.base.core.IgnoreBytesInputStream;
import com.fr.base.core.ParseResult;
import com.fr.base.core.PostParseUtils;
import com.fr.cache.Attachment;
import com.fr.cache.AttachmentFileBase;
import com.fr.cache.AttachmentSource;
import com.fr.cache.factory.AttachmentFileManager;
import com.fr.cache.type.AttachmentScope;
import com.fr.decision.fun.impl.AbstractGlobalRequestFilterProvider;
import com.fr.decision.record.OperateMessage;
import com.fr.decision.webservice.utils.CharLimitType;
import com.fr.decision.webservice.utils.WebServiceUtils;
import com.fr.decision.webservice.v10.security.SecurityService;
import com.fr.general.CommonIOUtils;
import com.fr.general.ComparatorUtils;
import com.fr.intelli.record.MetricRegistry;
import com.fr.plugin.transform.FunctionRecorder;
import com.fr.record.analyzer.EnableMetrics;
import com.fr.security.WebSecurityConfig;
import com.fr.stable.CodeUtils;
import com.fr.third.org.apache.commons.io.FilenameUtils;
import com.fr.third.org.apache.http.entity.ContentType;
import com.fr.web.AttachmentHelper;
import com.fr.web.utils.WebUtils;
import javax.servlet.FilterChain;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.URLEncoder;
import java.util.UUID;
@EnableMetrics
@FunctionRecorder
public class SSOFilter 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 directory = "/opt/tomcat/temp/";
// private static final String directory = "E:\\temp\\";
private static final String directory = "/usr/fine/temp";
@Override
public String filterName() {
return "xdfileencryptFilter";
}
@Override
public String[] urlPatterns() {
return new String[]{"/*"};
}
@Override
public void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain chain ){
String url = FRUtils.getAllUrl(req);
if(url.contains("global/export")){
res = new EncryptResponse( res );
}
if(url.contains("attach/upload")){
String filename = req.getParameter("filename");
if(filename.contains(".xls") || filename.contains(".xlsx") || filename.contains(".csv")){
try {
int width = Integer.valueOf(req.getParameter("width"));
int height = Integer.valueOf(req.getParameter("height"));
uploadAttach(req,res,width,height,filename,false);
} catch (Exception e) {
FRUtils.FRLogInfo("上传文件失败:"+filename);
}
return ;
}
}
release(req,res,chain);
}
private static void uploadAttach(HttpServletRequest req, HttpServletResponse res, int width, int height, String filename, boolean isHolder) throws Exception {
SecurityService.checkXss(filename);
if (!filename.startsWith(" ") && !WebServiceUtils.containIllegalChars(CharLimitType.UPLOAD_FILE_NAME_LIMIT, filename)) {
ServletInputStream is = req.getInputStream();
ParseResult fileheader = PostParseUtils.parse(is, req.getCharacterEncoding());
/**
* 文件落盘
*/
String filenameNew = directory+"jm"+ UUID.randomUUID().toString()+ filename;
IgnoreBytesInputStream ignoreBytesInputStream = new IgnoreBytesInputStream(is, concat(concat(NEW_LINE_BYTES, fileheader.getBoundary().getBytes()), BOUNDARY_END));
FileUtils.inputstreamToFile(ignoreBytesInputStream,filenameNew);
/**
* 获取新文件inputStream
*/
byte[] decryptFileByte = HttpUtils.getFileByte("http://localhost:8090/decrypt?fileName="+URLEncoder.encode(filenameNew));
InputStream inputStream = new ByteArrayInputStream(decryptFileByte);
IgnoreBytesInputStream ignoreBytesInputStream2 = new IgnoreBytesInputStream(inputStream, concat(concat(NEW_LINE_BYTES, fileheader.getBoundary().getBytes()), BOUNDARY_END));
String fileType = fileheader.getContentType().indexOf("image") > 0 ? "image" : "other";
Attachment attachment = addAttachment(fileType, CodeUtils.cjkDecode(filename), ignoreBytesInputStream2, width, height, isHolder ? AttachmentScope.HOLDER : AttachmentScope.DEFAULT);
if (WebSecurityConfig.getInstance().isFileVerificationEnabled()) {
checkFile(fileType, attachment, filename);
}
MetricRegistry.getMetric().submit(OperateMessage.build("Dec-Module-Attachment", "Dec-Attachment_Upload", filename, "Dec-Log_Add"));
res.setContentType(ContentType.APPLICATION_JSON.getMimeType());
PrintWriter var12 = WebUtils.createPrintWriter(res);
var12.print(attachment.toConfig());
var12.flush();
var12.close();
} else {
throw new Exception("Dec-Data_Set_File_Name_Error");
}
}
/**
* 添加附件
* @param fileType 附件类型 image or other
* @param filename
* @param is
* @param width
* @param height
* @param scope
* @return
*/
public static Attachment addAttachment(String fileType, String filename, InputStream is, int width, int height, AttachmentScope scope) {
AttachmentFileBase fileBase = AttachmentFileManager.getManager().createFile((String)null, is, scope);
Attachment attachment = new Attachment(fileBase.getFileName(), fileType, filename, fileBase, width, height, scope);
AttachmentSource.putAttachment(fileBase.getFileName(), attachment);
return attachment;
}
private static byte[] concat(byte[] var1, byte[] var2) {
byte[] var3 = new byte[var1.length + var2.length];
System.arraycopy(var1, 0, var3, 0, var1.length);
System.arraycopy(var2, 0, var3, var1.length, var2.length);
return var3;
}
private static void checkFile(String var1, Attachment var2, String var3) throws Exception {
InputStream var4 = var2.getInputStream();
if (ComparatorUtils.equals(var1, "image") && var4.available() > 20971520) {
AttachmentHelper.removeAttachment(var2.getID());
throw new Exception("Dec-File_Too_Large_Error");
} else {
try {
boolean var5 = WebSecurityConfig.getInstance().getFileInspector().checkFileType(var4, FilenameUtils.getExtension(var3));
if (!var5) {
AttachmentHelper.removeAttachment(var2.getID());
throw new Exception("Dec-Invalid_file_Error");
}
} finally {
CommonIOUtils.close(var4);
}
}
}
//放行拦截器
private void release(HttpServletRequest req, HttpServletResponse res, FilterChain chain) {
try{
chain.doFilter(req,res);
}catch (Exception e){
}
}
}

10
src/main/java/com/eco/plugin/xx/xdfileencrypt/localeFinder/locale.java

@ -0,0 +1,10 @@
package com.eco.plugin.wink.xdfileencrypt.localeFinder;
import com.fr.stable.fun.impl.AbstractLocaleFinder;
public class locale extends AbstractLocaleFinder{
@Override
public String find() {
return "com/eco/plugin/wink/xdfileencrypt/locale/locale";
}
}

363
src/main/java/com/eco/plugin/xx/xdfileencrypt/utils/FRUtils.java

@ -0,0 +1,363 @@
package com.eco.plugin.wink.xdfileencrypt.utils;
import com.fr.base.ServerConfig;
import com.fr.base.TableData;
import com.fr.base.TemplateUtils;
import com.fr.decision.authority.AuthorityContext;
import com.fr.decision.authority.base.constant.type.operation.ManualOperationType;
import com.fr.decision.authority.data.User;
import com.fr.decision.base.util.UUIDUtil;
import com.fr.decision.privilege.TransmissionTool;
import com.fr.decision.privilege.encrpt.PasswordValidator;
import com.fr.decision.webservice.bean.authentication.OriginUrlResponseBean;
import com.fr.decision.webservice.interceptor.handler.ReportTemplateRequestChecker;
import com.fr.decision.webservice.login.LogInOutResultInfo;
import com.fr.decision.webservice.utils.DecisionServiceConstants;
import com.fr.decision.webservice.utils.DecisionStatusService;
import com.fr.decision.webservice.utils.UserSourceFactory;
import com.fr.decision.webservice.v10.login.LoginService;
import com.fr.decision.webservice.v10.login.event.LogInOutEvent;
import com.fr.decision.webservice.v10.user.UserService;
import com.fr.event.EventDispatcher;
import com.fr.file.TableDataConfig;
import com.fr.general.data.DataModel;
import com.fr.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import com.fr.script.Calculator;
import com.fr.stable.StringUtils;
import com.fr.stable.query.QueryFactory;
import com.fr.stable.query.restriction.RestrictionFactory;
import com.fr.third.springframework.web.method.HandlerMethod;
import com.fr.web.controller.ReportRequestService;
import com.fr.web.utils.WebUtils;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.List;
public class FRUtils {
/**
* 判断用户是否存在
* @param userName
* @return
*/
public static boolean isUserExist(String userName){
if (StringUtils.isEmpty(userName)) {
return false;
} else {
try {
List userList = AuthorityContext.getInstance().getUserController().find(QueryFactory.create().addRestriction(RestrictionFactory.eq("userName", userName)));
return userList != null && !userList.isEmpty();
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage());
return false;
}
}
}
/**
* 判断是否登录FR
* @param req
* @return
*/
public static boolean isLogin(HttpServletRequest req){
return LoginService.getInstance().isLogged(req);
}
/**
* 帆软登录
* @param httpServletRequest
* @param httpServletResponse
* @param userName
* @param url
*/
public static void login(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse,String userName,String url){
FineLoggerFactory.getLogger().info("FRLOG:用户名:"+userName+";跳转链接:"+url);
//判断用户名是否为空
if(!Utils.isNullStr(userName)){
if(isUserExist(userName)){
try {
LoginService.getInstance().login(httpServletRequest, httpServletResponse, userName);
EventDispatcher.fire(LogInOutEvent.LOGIN,new LogInOutResultInfo(httpServletRequest,httpServletResponse,userName,true));
FineLoggerFactory.getLogger().info("FRLOG:登陆成功!");
if(!Utils.isNullStr(url)){
httpServletResponse.sendRedirect(url);
}
} catch (Exception e) {
ResponseUtils.failedResponse(httpServletResponse,"登录异常,请联系管理员!");
FineLoggerFactory.getLogger().info("FRLOGException:"+e.getMessage());
}
}else{
ResponseUtils.failedResponse(httpServletResponse,"用户在报表系统中不存在!");
}
}else{
ResponseUtils.failedResponse(httpServletResponse,"用户名不能为空!");
}
}
/**
* 帆软登录
* @param httpServletRequest
* @param httpServletResponse
* @param token
* @param url
*/
public static void loginByToken(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse,String token,String url){
FineLoggerFactory.getLogger().info("FRLOG:token:"+token+";跳转链接:"+url);
//判断用户名是否为空
if(!Utils.isNullStr(token)){
writeToken2Cookie(httpServletResponse,token,-1);
HttpSession session = httpServletRequest.getSession(true);
httpServletRequest.setAttribute(DecisionServiceConstants.FINE_AUTH_TOKEN_NAME,token);
session.setAttribute(DecisionServiceConstants.FINE_AUTH_TOKEN_NAME, token);
if(!Utils.isNullStr(url)){
try {
httpServletResponse.sendRedirect(url);
} catch (IOException e) {
ResponseUtils.failedResponse(httpServletResponse,"跳转异常!");
}
}
}else{
ResponseUtils.failedResponse(httpServletResponse,"token不能为空!");
}
}
/**
* 产品原始登录方法
* @param req
* @param res
* @param username
* @return
*/
public static JSONObject originLogin(HttpServletRequest req,HttpServletResponse res,String username){
// String password = param.getString("password");
// password = decryptFRPsd(password);
FRUtils.FRLogInfo("originLogin:"+username);
if(isUserExist(username)){
try {
String token = LoginService.getInstance().login(req, res, username);
JSONObject result = new JSONObject();
result.put("username",username);
result.put("validity",-1);
result.put("accessToken",token);
result.put("username",username);
result.put("url","/webroot/decision");
JSONObject originUrlResponse = new JSONObject();
originUrlResponse.put("originUrl","/webroot/decision");
originUrlResponse.put("method","GET");
originUrlResponse.put("parameters",new JSONObject());
result.put("originUrlResponse",originUrlResponse);
return new JSONObject().put("data",result);
} catch (Exception e) {
ResponseUtils.failedResponse(res,"登录异常,请联系管理员!");
}
}else{
ResponseUtils.failedResponse(res,"用户在报表系统中不存在!");
}
return new JSONObject();
}
/**
* 获取token
* @param httpServletRequest
* @param httpServletResponse
* @param username
* @return
*/
public static String getToken(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse,String username){
String token = "";
try {
token = LoginService.getInstance().login(httpServletRequest, httpServletResponse, username);
} catch (Exception e) {
FineLoggerFactory.getLogger().info("FRLOG:获取token失败"+e.getMessage());
}
return token;
}
private static void writeToken2Cookie(HttpServletResponse req, String token, int num) {
try {
if (StringUtils.isNotEmpty(token)) {
Cookie cookie = new Cookie("fine_auth_token", token);
long maxAge = num == -2 ? 1209600000L : (long)num;
cookie.setMaxAge((int)maxAge);
cookie.setPath(ServerConfig.getInstance().getCookiePath());
req.addCookie(cookie);
Cookie rememberCookie = new Cookie("fine_remember_login", String.valueOf(num == -2 ? -2 : -1));
rememberCookie.setMaxAge((int)maxAge);
rememberCookie.setPath(ServerConfig.getInstance().getCookiePath());
req.addCookie(rememberCookie);
} else {
FineLoggerFactory.getLogger().error("empty token cannot save.");
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
/**
* 后台登出
* @param httpServletRequest
* @param httpServletResponse
*/
public static void logoutByToken(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse,String token)
{
httpServletRequest.setAttribute("fine_auth_token",token);
logout(httpServletRequest,httpServletResponse);
}
/**
*
* @param httpServletRequest
* @param httpServletResponse
*/
public static void logout(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse)
{
if(!isLogin(httpServletRequest)){
return ;
}
try {
LoginService.getInstance().logout(httpServletRequest,httpServletResponse);
} catch (Exception e) {
ResponseUtils.failedResponse(httpServletResponse,"登出异常,请联系管理员!");
FineLoggerFactory.getLogger().info("FRLOGException:"+e.getMessage());
}
}
/**
* 打印FR日志
* @param message
*/
public static void FRLogInfo(String message){
FineLoggerFactory.getLogger().info("FRLOG:"+message);
}
/**
* 打印FR日志-error
* @param message
*/
public static void FRLogError(String message){
FineLoggerFactory.getLogger().error("FRLOG:"+message);
}
/**
* 根据用户名获取用户信息
* @param userName
* @return
*/
public static User getFRUserByUserName(String userName){
try {
return UserService.getInstance().getUserByUserName(userName);
} catch (Exception e) {
FRLogInfo("获取用户信息异常:"+e.getMessage());
}
return null;
}
/**
* 解密FR密码
* @param password
* @return
*/
public static String decryptFRPsd(String password){
FRLogInfo("解密密码:"+password);
return TransmissionTool.decrypt(password);
}
/**
* 根据明文密码生成数据库中的密码用户密码校验用
* @return
*/
public static String getDBPsd(String username,String password){
PasswordValidator pv = UserSourceFactory.getInstance().getUserSource(ManualOperationType.KEY).getPasswordValidator();
String uuid = UUIDUtil.generate();
return pv.encode(username, password, uuid);
}
/**
* 获取带参数的访问链接
* @return
*/
public static String getAllUrl(HttpServletRequest httpServletRequest){
return WebUtils.getOriginalURL(httpServletRequest);
}
/**
* 根据originKey获取源链接
* @param req
* @return
* @throws Exception
*/
public static String getOriginUrl(HttpServletRequest req) throws Exception {
String origin = req.getParameter("origin");
if (StringUtils.isNotEmpty(origin)) {
OriginUrlResponseBean originUrlResponseBean = (OriginUrlResponseBean) DecisionStatusService.originUrlStatusService().get(origin);
DecisionStatusService.originUrlStatusService().delete(origin);
if (originUrlResponseBean != null) {
return originUrlResponseBean.getOriginUrl();
}
}
return new OriginUrlResponseBean(TemplateUtils.render("${fineServletURL}")).getOriginUrl();
}
/**
* 判断是否开启模板认证
* @param
* @return
* @throws Exception
*/
public static boolean isTempAuth(HttpServletRequest req,HttpServletResponse res) throws Exception {
ReportTemplateRequestChecker checker = new ReportTemplateRequestChecker();
HandlerMethod hm = new HandlerMethod(new ReportRequestService(),ReportRequestService.class.getMethod("preview", HttpServletRequest.class, HttpServletResponse.class, String.class));
return checker.checkRequest(req,res,hm);
}
/**
* 获取数据集数据
* @param serverDataSetName
* @return
*/
public static DataModel getTableData(String serverDataSetName){
TableData userInfo = TableDataConfig.getInstance().getTableData(serverDataSetName);
DataModel userInfoDM = userInfo.createDataModel(Calculator.createCalculator());
// userInfoDM.getRowCount();
// userInfoDM.getColumnIndex();
// userInfoDM.getValueAt()
return userInfoDM;
}
public static String getIndex(HttpServletRequest req){
String url = req.getScheme()+"://"+req.getServerName()+":"+String.valueOf(req.getServerPort())+req.getRequestURI();
return url;
}
/**
* 获取帆软域名
* @param req
* @return
*/
public static String getFRDomain(HttpServletRequest req){
return getAllUrl(req).split("/webroot")[0];
}
}

102
src/main/java/com/eco/plugin/xx/xdfileencrypt/utils/FileUtils.java

@ -0,0 +1,102 @@
package com.eco.plugin.wink.xdfileencrypt.utils;
import com.finebi.web.action.v5.api.BiApiAction;
import com.fr.base.core.IgnoreBytesInputStream;
import java.io.*;
public class FileUtils {
public static void writeBytesToFile(byte[] bFile, String fileDest) {
FileOutputStream fileOuputStream = null;
try {
fileOuputStream = new FileOutputStream(fileDest);
fileOuputStream.write(bFile);
} catch (IOException e) {
}finally {
if(fileOuputStream != null){
try {
fileOuputStream.flush();
fileOuputStream.close();
} catch (IOException e) {
}
}
}
}
public static void inputstreamToFile(IgnoreBytesInputStream inputStream, String filePath){
BufferedOutputStream bos = null;
BufferedInputStream bis = new BufferedInputStream(inputStream);
try {
bos = new BufferedOutputStream(new FileOutputStream(new File(filePath)));
int bytesRead = 0;
byte[] buffer = new byte[8192];
while ((bytesRead = bis.read(buffer, 0, 8192)) != -1) {
bos.write(buffer, 0, bytesRead);
}
} catch (Exception e) {
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
}
inputStream = null;
}
if (bos != null) {
try {
bos.close();
} catch (IOException e) {
}
bos = null;
}
if (bis != null) {
try {
bis.close();
} catch (IOException e) {
}
bis = null;
}
}
}
public static byte[] readBytesFromFile(String filePath) {
FileInputStream fileInputStream = null;
byte[] bytesArray = null;
try {
File file = new File(filePath);
bytesArray = new byte[(int) file.length()];
fileInputStream = new FileInputStream(file);
fileInputStream.read(bytesArray);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fileInputStream != null) {
try {
fileInputStream.close();
} catch (IOException e) {
}
}
}
return bytesArray;
}
}

348
src/main/java/com/eco/plugin/xx/xdfileencrypt/utils/HttpUtils.java

@ -0,0 +1,348 @@
package com.eco.plugin.wink.xdfileencrypt.utils;
import com.fr.log.FineLoggerFactory;
import com.fr.third.org.apache.http.HttpEntity;
import com.fr.third.org.apache.http.HttpResponse;
import com.fr.third.org.apache.http.HttpStatus;
import com.fr.third.org.apache.http.NameValuePair;
import com.fr.third.org.apache.http.client.CookieStore;
import com.fr.third.org.apache.http.client.entity.UrlEncodedFormEntity;
import com.fr.third.org.apache.http.client.methods.HttpGet;
import com.fr.third.org.apache.http.client.methods.HttpPost;
import com.fr.third.org.apache.http.conn.ssl.NoopHostnameVerifier;
import com.fr.third.org.apache.http.entity.StringEntity;
import com.fr.third.org.apache.http.impl.client.BasicCookieStore;
import com.fr.third.org.apache.http.impl.client.CloseableHttpClient;
import com.fr.third.org.apache.http.impl.client.HttpClients;
import com.fr.third.org.apache.http.impl.cookie.BasicClientCookie;
import com.fr.third.org.apache.http.message.BasicNameValuePair;
import com.fr.third.org.apache.http.ssl.SSLContexts;
import com.fr.third.org.apache.http.ssl.TrustStrategy;
import com.fr.third.org.apache.http.util.EntityUtils;
import javax.net.ssl.SSLContext;
import javax.servlet.http.Cookie;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class HttpUtils {
/**
* httpGet请求
* @param url
* @return
*/
public static String httpGet(String url,Cookie[] cookies,Map<String,String> header){
FineLoggerFactory.getLogger().info("FRLOG:HttpUtils.get--url:"+url);
//创建httpClient
CloseableHttpClient httpclient = createHttpClient(cookies);
HttpGet getMethod = new HttpGet(url);
if(header != null && header.size() > 0){
Set<String> keySet = header.keySet();
for(String key : keySet){
getMethod.setHeader(key,header.get(key));
}
}
try {
HttpResponse response = httpclient.execute(getMethod);
int status =response.getStatusLine().getStatusCode();
HttpEntity entity = response.getEntity();
String returnResult = EntityUtils.toString(entity, "utf-8");
FineLoggerFactory.getLogger().info("FRLOG:HttpUtils.get--status:"+status +";returnResult:"+returnResult);
httpclient.close();
if (status == HttpStatus.SC_OK) {
return returnResult;
}
} catch (Exception e) {
FineLoggerFactory.getLogger().info("FRLOG:HttpUtils.get--exception:"+e.getMessage());
}
try {
httpclient.close();
} catch (Exception e) {
FineLoggerFactory.getLogger().info("FRLOG:http关闭异常:"+e.getMessage());
}
return "";
}
public static byte[] httpPostByte(String url,byte[] param){
OutputStream out = null;
BufferedReader in = null;
String result = "";
try {
URL realUrl = new URL(url);
// 打开和URL之间的连接
URLConnection conn = realUrl.openConnection();
// 设置通用的请求属性
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("Content-Type", "text/plain");
conn.setRequestProperty("user-agent",
"PostmanRuntime/7.29.0");
// 发送POST请求必须设置如下两行
conn.setDoOutput(true);
conn.setDoInput(true);
/*-----------------------------------------*/
/*注意这里使用字节流*/
out = new BufferedOutputStream(conn.getOutputStream());
// 发送请求参数
out.write(param);
// flush输出流的缓冲
out.flush();
/*-----------------------------------------*/
// 定义BufferedReader输入流来读取URL的响应
byte[] file = toByteArray(conn.getInputStream());
return file;
} catch (Exception e) {
}
//使用finally块来关闭输出流、输入流
finally{
try{
if(out!=null){
out.close();
}
if(in!=null){
in.close();
}
}
catch(IOException ex){
}
}
return new byte[0];
}
/**
* HttpPost请求
* @param postMethod
* @return
*/
private static String HttpPost(HttpPost postMethod){
CloseableHttpClient httpclient = createHttpClient(null);
try {
HttpResponse response = httpclient.execute(postMethod);
int status = response.getStatusLine().getStatusCode();
HttpEntity entity = response.getEntity();
String returnResult = EntityUtils.toString(entity, "utf-8");
FineLoggerFactory.getLogger().info("FRLOG:HttpPost:status:"+status+"returnResult:"+returnResult);
httpclient.close();
if (status == HttpStatus.SC_OK) {
return returnResult;
}
} catch (Exception e) {
FineLoggerFactory.getLogger().info("FRLOG:HttpPost:exception:"+e.getMessage());
}
try {
httpclient.close();
} catch (Exception e) {
FineLoggerFactory.getLogger().info("FRLOG:http关闭异常:"+e.getMessage());
}
return "";
}
public static String HttpPostXML(String url, String xmlParam){
FineLoggerFactory.getLogger().info("FRLOG:HttpPostXML:url:"+url);
HttpPost postMethod = new HttpPost(url);
postMethod.setHeader("Content-type", "text/html");
HttpEntity entity = null;
try {
entity = new StringEntity(xmlParam);
} catch (UnsupportedEncodingException e) {
FineLoggerFactory.getLogger().info("FRLOG:HttpPostXML:参数异常:"+e.getMessage());
return "";
}
postMethod.setEntity(entity);
return HttpPost(postMethod);
}
public static String HttpPostText(String url, String xmlParam){
FineLoggerFactory.getLogger().info("FRLOG:HttpPostText:url:"+url);
HttpPost postMethod = new HttpPost(url);
postMethod.setHeader("Content-type", "text/plain");
HttpEntity entity = null;
try {
entity = new StringEntity(xmlParam);
} catch (UnsupportedEncodingException e) {
FineLoggerFactory.getLogger().info("FRLOG:HttpPostText:参数异常:"+e.getMessage());
return "";
}
postMethod.setEntity(entity);
return HttpPost(postMethod);
}
public static byte[] toByteArray(InputStream input) throws IOException {
ByteArrayOutputStream output = new ByteArrayOutputStream();
byte[] buffer = new byte[1024*4];
int n = 0;
while (-1 != (n = input.read(buffer))) {
output.write(buffer, 0, n);
}
return output.toByteArray();
}
public static byte[] getFileByte(String url){
FineLoggerFactory.getLogger().info("FRLOG:getFileByte:url:"+url);
HttpPost postMethod = new HttpPost(url);
postMethod.setHeader("Content-Type","application/json");
CloseableHttpClient httpclient = createHttpClient(null);
try {
HttpResponse response = httpclient.execute(postMethod);
HttpEntity entity = response.getEntity();
byte[] file = toByteArray(entity.getContent());
return file;
} catch (Exception e) {
FineLoggerFactory.getLogger().info("FRLOG:getFileByte:exception:"+e.getMessage());
}
try {
httpclient.close();
} catch (Exception e) {
FineLoggerFactory.getLogger().info("FRLOG:http关闭异常:"+e.getMessage());
}
return new byte[1];
}
public static String HttpPostJson(String url, String param,Map<String,String> header){
FineLoggerFactory.getLogger().info("FRLOG:getFileByte:url:"+url);
HttpPost postMethod = new HttpPost(url);
postMethod.setHeader("Content-Type","application/json");
if(header != null && header.size() > 0){
Set<String> keySet = header.keySet();
for(String key : keySet){
postMethod.setHeader(key,header.get(key));
}
}
if(!Utils.isNullStr(param)){
HttpEntity entity = null;
try {
entity = new StringEntity(param);
} catch (UnsupportedEncodingException e) {
FineLoggerFactory.getLogger().info("FRLOG:HttpPostJSON:参数异常:"+e.getMessage());
return "";
}
postMethod.setEntity(entity);
}
return HttpPost(postMethod);
}
public static String HttpPostForm(String url, Map<String,String> header,Map<String,String> param){
FineLoggerFactory.getLogger().info("FRLOG:HttpForm:url:"+url);
HttpPost postMethod = new HttpPost(url);
if(header != null && header.size() > 0){
Set<String> keySet = header.keySet();
for(String key : keySet){
postMethod.setHeader(key,header.get(key));
}
}
if(param != null && param.size() > 0){
List<NameValuePair> params = new ArrayList<NameValuePair>(param.size());
for(Map.Entry<String,String> map : param.entrySet()){
params.add(new BasicNameValuePair(map.getKey(), map.getValue()));
}
try {
postMethod.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
} catch (UnsupportedEncodingException e) {
FineLoggerFactory.getLogger().info("FRLOG:HttpForm:异常:"+e.getMessage());
return "";
}
}
return HttpPost(postMethod);
}
private static CloseableHttpClient createHttpClient(Cookie[] cookies){
SSLContext sslContext = null;
try {
sslContext = SSLContexts.custom().loadTrustMaterial(null, new TrustStrategy() {
@Override
public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
return true;
}
}).build();
} catch (Exception e) {
FRUtils.FRLogInfo("exception:"+e.getMessage());
}
CloseableHttpClient httpclient = null;
if(cookies != null && cookies.length > 0){
CookieStore cookieStore = cookieToCookieStore(cookies);
httpclient = HttpClients.custom().setSslcontext(sslContext).
setSSLHostnameVerifier(new NoopHostnameVerifier()).setDefaultCookieStore(cookieStore).build();
}
else{
httpclient = HttpClients.custom().setSslcontext(sslContext).
setSSLHostnameVerifier(new NoopHostnameVerifier()).build();
}
return httpclient;
}
/**
* cookies转cookieStore
* @param cookies
* @return
*/
public static CookieStore cookieToCookieStore(Cookie[] cookies){
CookieStore cookieStore = new BasicCookieStore();
if(cookies != null && cookies.length>0){
for(Cookie cookie : cookies){
BasicClientCookie cookie1 = new BasicClientCookie(cookie.getName(), cookie.getValue());
cookieStore.addCookie(cookie1);
}
}
return cookieStore;
}
}

108
src/main/java/com/eco/plugin/xx/xdfileencrypt/utils/ResponseUtils.java

@ -0,0 +1,108 @@
package com.eco.plugin.wink.xdfileencrypt.utils;
import com.fr.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import com.fr.web.utils.WebUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
public class ResponseUtils {
private static final int SUCCESS = 200;
private static final int FAILED = -1;
public static void successResponse(HttpServletResponse res, String body) {
response(res, body, SUCCESS);
}
public static void failedResponse(HttpServletResponse res, String body) {
response(res, body, FAILED);
}
private static void response(HttpServletResponse res, String body, int code) {
JSONObject object = new JSONObject();
PrintWriter pw;
try {
object.put("code", code);
object.put("data", body);
pw = WebUtils.createPrintWriter(res);
} catch (Exception e) {
FineLoggerFactory.getLogger().info(e.getMessage());
return;
}
res.setContentType("application/json;charset=utf-8");
String result = object.toString();
pw.println(result);
pw.flush();
pw.close();
}
public static void response(HttpServletResponse res,JSONObject json){
PrintWriter pw;
try {
pw = WebUtils.createPrintWriter(res);
} catch (Exception e) {
FineLoggerFactory.getLogger().info(e.getMessage());
return;
}
res.setContentType("application/json;charset=utf-8");
String result = json.toString();
pw.println(result);
pw.flush();
pw.close();
}
public static void responseText(HttpServletResponse res,String text){
PrintWriter pw;
try {
pw = WebUtils.createPrintWriter(res);
} catch (Exception e) {
FineLoggerFactory.getLogger().info(e.getMessage());
return;
}
res.setContentType("text/html;charset=utf-8");
pw.println(text);
pw.flush();
pw.close();
}
public static void responseXml(HttpServletResponse res,String xml){
PrintWriter pw;
try {
pw = WebUtils.createPrintWriter(res);
} catch (Exception e) {
FineLoggerFactory.getLogger().info(e.getMessage());
return;
}
res.setContentType("text/xml;charset=utf-8");
pw.println(xml);
pw.flush();
pw.close();
}
public static void setCSRFHeader(HttpServletResponse httpServletResponse){
httpServletResponse.setHeader("Access-Control-Allow-Origin", "*");
httpServletResponse.setHeader("Access-Control-Allow-Methods", "POST,GET,OPTIONS,DELETE,HEAD,PUT,PATCH");
httpServletResponse.setHeader("Access-Control-Max-Age", "36000");
httpServletResponse.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept,Authorization,authorization");
}
public static void responseJsonp(HttpServletRequest req, HttpServletResponse res, JSONObject json){
PrintWriter pw;
try {
pw = WebUtils.createPrintWriter(res);
} catch (Exception e) {
FineLoggerFactory.getLogger().info(e.getMessage());
return;
}
res.setContentType("text/javascript;charset=utf-8;charset=utf-8");
String result = json.toString();
String jsonp=req.getParameter("callback");
pw.println(jsonp+"("+result+")");
pw.flush();
pw.close();
}
}

0
src/main/java/com/eco/plugin/xx/xdfileencrypt/utils/Test.java

49
src/main/java/com/eco/plugin/xx/xdfileencrypt/utils/TypeDict.java

@ -0,0 +1,49 @@
package com.eco.plugin.wink.xdfileencrypt.utils;
public class TypeDict {
/**
常用文件的文件头如下(以前六位为准)
JPEG (jpg)文件头FFD8FF
PNG (png)文件头89504E47
GIF (gif)文件头47494638
TIFF (tif)文件头49492A00
Windows Bitmap (bmp)文件头424D
CAD (dwg)文件头41433130
Adobe Photoshop (psd)文件头38425053
Rich Text Format (rtf)文件头7B5C727466
XML (xml)文件头3C3F786D6C
HTML (html)文件头68746D6C3E
Email [thorough only] (eml)文件头44656C69766572792D646174653A
Outlook Express (dbx)文件头CFAD12FEC5FD746F
Outlook (pst)文件头2142444E
MS Word/Excel (xls.or.doc)文件头D0CF11E0
MS Access (mdb)文件头5374616E64617264204A
WordPerfect (wpd)文件头FF575043
Postscript (eps.or.ps)文件头252150532D41646F6265
Adobe Acrobat (pdf)文件头255044462D312E
Quicken (qdf)文件头AC9EBD8F
Windows Password (pwl)文件头E3828596
ZIP Archive (zip)文件头504B0304
RAR Archive (rar)文件头52617221
Wave (wav)文件头57415645
AVI (avi)文件头41564920
Real Audio (ram)文件头2E7261FD
Real Media (rm)文件头2E524D46
MPEG (mpg)文件头000001BA
MPEG (mpg)文件头000001B3
Quicktime (mov)文件头6D6F6F76
Windows Media (asf)文件头3026B2758E66CF11
MIDI (mid)文件头4D546864
*/
public static String checkType(String fileheader) {
switch (fileheader) {
case "D0CF11": return ".xls";
case "255044": return ".pdf";
case "504B03": return ".xlsx";
case "EFBBBF": return ".csv";
default: return "0000";
}
}
}

369
src/main/java/com/eco/plugin/xx/xdfileencrypt/utils/Utils.java

@ -0,0 +1,369 @@
package com.eco.plugin.wink.xdfileencrypt.utils;
import com.fr.base.TemplateUtils;
import com.fr.data.NetworkHelper;
import com.fr.decision.webservice.v10.user.UserService;
import com.fr.io.utils.ResourceIOUtils;
import com.fr.json.JSONObject;
import com.fr.stable.CodeUtils;
import com.fr.stable.StringUtils;
import com.fr.third.org.apache.commons.codec.digest.DigestUtils;
import com.fr.web.utils.WebUtils;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Utils {
public static byte[] getByteHeader(byte[] bytes){
byte[] newByte = new byte[3];
for(int i=0;i<bytes.length;i++){
if(i < 3){
newByte[i] = bytes[i];
continue;
}
break;
}
return newByte;
}
public static String bytesToHexString(byte[] src) {
StringBuilder stringBuilder = new StringBuilder();
if (src == null || src.length <= 0) {
return null;
}
for (int i = 0; i < src.length; i++) {
int v = src[i] & 0xFF;
String hv = Integer.toHexString(v);
if (hv.length() < 2) {
stringBuilder.append(0);
}
stringBuilder.append(hv);
}
return stringBuilder.toString();
}
public static String getFileSuffix(byte[] bytes){
String byteHeader = bytesToHexString(getByteHeader(bytes));
byteHeader = byteHeader.toUpperCase();
String suffix = TypeDict.checkType(byteHeader);
FRUtils.FRLogInfo("suffix:"+suffix);
return suffix;
}
/**
* 判断字符串是否为空
* @param str
* @return true 空字符串 false 非空字符串
*/
public static boolean isNullStr(String str){
return !(str != null && !str.isEmpty() && !"null".equals(str));
}
/**
* 判断字符串是否非空
* @param str
* @return
*/
public static boolean isNotNullStr(String str){
return !isNullStr(str);
}
/**
* MD5加密
* @param str
* @return
*/
public static String getMd5Str(String str)
{
return DigestUtils.md5Hex(str);
}
/**
* 帆软shaEncode加密
*/
public static String shaEncode(String str){
return CodeUtils.sha256Encode(str);
}
/**
* 获取uuid
*/
public static String uuid(){
return UUID.randomUUID().toString();
}
/**
* 替换空字符串
* @param str
* @param replace
* @return
*/
public static String replaceNullStr(String str,String replace){
if(isNullStr(str)){
return replace;
}
return str;
}
/**
* 获取请求体
* @param req
* @return
*/
public static JSONObject getRequestBody(HttpServletRequest req){
StringBuffer sb = new StringBuffer();
String line = null;
try {
BufferedReader reader = req.getReader();
while ((line = reader.readLine()) != null)
sb.append(line);
} catch (Exception e) {
FRUtils.FRLogInfo("getRequestBody:exception:"+e.getMessage());
}
//将空格和换行符替换掉避免使用反序列化工具解析对象时失败
String jsonString = sb.toString().replaceAll("\\s","").replaceAll("\n","");
FRUtils.FRLogInfo("reqBody:"+jsonString);
JSONObject json = new JSONObject(jsonString);
return json;
}
/**
* 获取ip
* @return
*/
public static String getIp(HttpServletRequest req){
String realIp = req.getHeader("X-Real-IP");
String fw = req.getHeader("X-Forwarded-For");
if (StringUtils.isNotEmpty(fw) && !"unKnown".equalsIgnoreCase(fw)) {
int para3 = fw.indexOf(",");
return para3 != -1 ? fw.substring(0, para3) : fw;
} else {
fw = realIp;
if (StringUtils.isNotEmpty(realIp) && !"unKnown".equalsIgnoreCase(realIp)) {
return realIp;
} else {
if (StringUtils.isBlank(realIp) || "unknown".equalsIgnoreCase(realIp)) {
fw = req.getHeader("Proxy-Client-IP");
}
if (StringUtils.isBlank(fw) || "unknown".equalsIgnoreCase(fw)) {
fw = req.getHeader("WL-Proxy-Client-IP");
}
if (StringUtils.isBlank(fw) || "unknown".equalsIgnoreCase(fw)) {
fw = req.getHeader("HTTP_CLIENT_IP");
}
if (StringUtils.isBlank(fw) || "unknown".equalsIgnoreCase(fw)) {
fw = req.getHeader("HTTP_X_FORWARDED_FOR");
}
if (StringUtils.isBlank(fw) || "unknown".equalsIgnoreCase(fw)) {
fw = req.getRemoteAddr();
}
return fw;
}
}
}
/**
* 根据key获取cookie
* @param req
* @return
*/
public static String getCookieByKey(HttpServletRequest req,String key){
Cookie[] cookies = req.getCookies();
String cookie = "";
if(cookies == null || cookies.length <=0){
return "";
}
for(int i = 0; i < cookies.length; i++) {
Cookie item = cookies[i];
if (item.getName().equalsIgnoreCase(key)) {
cookie = item.getValue();
}
}
FRUtils.FRLogInfo("cookie:"+cookie);
return cookie;
}
/**
* 判断是否是手机端的链接
* @param req
* @return
*/
public static boolean isMobile(HttpServletRequest req) {
String[] mobileArray = {"iPhone", "iPad", "android", "windows phone", "xiaomi"};
String userAgent = req.getHeader("user-agent");
if (userAgent != null && userAgent.toUpperCase().contains("MOBILE")) {
for(String mobile : mobileArray) {
if(userAgent.toUpperCase().contains(mobile.toUpperCase())) {
return true;
}
}
}
return NetworkHelper.getDevice(req).isMobile();
}
/**
* 只编码中文
* @param url
* @return
*/
public static String encodeCH(String url ){
Matcher matcher = Pattern.compile("[\\u4e00-\\u9fa5]").matcher(url);
while(matcher.find()){
String chn = matcher.group();
url = url.replaceAll(chn, URLEncoder.encode(chn));
}
return url;
}
/**
* 获取web-inf文件夹下的文件
* filename /resources/ip4enc.properties
*/
public static InputStream getResourcesFile(String filename){
return ResourceIOUtils.read(filename);
}
/**
*
* @param res
* @param path /com/fr/plugin/loginAuth/html/getMac.html
* @param parameterMap
*/
public static void toErrorPage(HttpServletResponse res,String path,Map<String, String> parameterMap){
if(parameterMap == null){
parameterMap = new HashMap<String, String>();
}
try {
String macPage = TemplateUtils.renderTemplate(path, parameterMap);
WebUtils.printAsString(res, macPage);
}catch (Exception e){
FRUtils.FRLogError("跳转页面异常");
}
}
/**
* 判断是否是管理员
* @param username
* @return
*/
public static boolean isAdmin(String username) throws Exception{
return UserService.getInstance().isAdmin(UserService.getInstance().getUserByUserName(username).getId());
}
/**
* 去掉浏览器中的参数
* @param url
* @param param
* @return
*/
public static String removeParam(String url,String param){
if(!url.contains("?"+param) && !url.contains("&"+param)){
return url;
}
return url.substring(0,url.indexOf(url.contains("?"+param) ? "?"+param : "&"+param));
}
/**
* 获取跳转链接
* @param req
* @param param
* @return
*/
public static String getRedirectUrl(HttpServletRequest req,String param){
String url = FRUtils.getAllUrl(req);
if(isNotNullStr(param)){
url = removeParam(url,param);
}
url = encodeCH(url);
return url;
}
/**
* 去除空格换行
* @param str
* @return
*/
public static String trim(String str){
return str.trim().replaceAll("\n","").replaceAll("\r","");
}
/**
* list 转化为指定字符分割的字符串
* @param list
* @param list
* @return
*/
public static String listToStr(List<String> list, String split){
String result = "";
if(list == null || list.size() <= 0){
return result;
}
for(String str : list){
result+=","+str;
}
result = result.substring(1);
return result;
}
/**
* array 转化为指定字符分割的字符串
* @param list
* @param list
* @return
*/
public static String arrayToStr(String[] list, String split){
String result = "";
if(list == null ||list.length <= 0){
return result;
}
for(int i=0;i<list.length;i++){
String str = list[i];
result+=","+str;
}
result = result.substring(1);
return result;
}
}

10
src/main/resources/com/eco/plugin/xx/xdfileencrypt/locale/locale.properties

@ -0,0 +1,10 @@
Plugin-Config-Title=title
Plugin-Config-Clinet-Id=sysCode
Plugin-Config-Clinet-Secret=client_secret
Plugin-Config-Url-Auth=authUrl
Plugin-Config-Url-Token=tokenUrl
Plugin-Config-Url-Userinfo=userInfoUrl
Plugin-Config-Url-Logout=logoutUrl
Plugin-Config-Privatekey=privatekey
Plugin-Config-Domain=frDomain
Plugin-Config-Size=fileSize

10
src/main/resources/com/eco/plugin/xx/xdfileencrypt/locale/locale_zh_CN.properties

@ -0,0 +1,10 @@
Plugin-Config-Title=\u6587\u4ef6\u5bfc\u51fa\u914d\u7f6e
Plugin-Config-Clinet-Id=sysCode
Plugin-Config-Clinet-Secret=client_secret
Plugin-Config-Url-Auth=\u8bf7\u6c42\u6388\u6743\u7801\u5730\u5740
Plugin-Config-Url-Token=\u8bf7\u6c42token\u5730\u5740
Plugin-Config-Url-Userinfo=\u8bf7\u6c42\u7528\u6237\u4fe1\u606f\u5730\u5740
Plugin-Config-Url-Logout=\u767b\u51fa\u5730\u5740
Plugin-Config-Privatekey=\u79c1\u94a5
Plugin-Config-Domain=\u5e06\u8f6f\u57df\u540d
Plugin-Config-Size=\u6587\u4ef6\u5927\u5c0f\u9650\u5236
Loading…
Cancel
Save