mirror of
https://github.com/KOHGYLW/kiftd-source.git
synced 2025-01-09 04:27:56 +08:00
update to v1.0.23 优化了永久资源链接功能,增强保密性
This commit is contained in:
parent
93c1bfc7bf
commit
1172011315
30
mybatisResource/mapperXML/PropertiesMapper.xml
Normal file
30
mybatisResource/mapperXML/PropertiesMapper.xml
Normal file
@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="kohgylw.kiftd.server.mapper.PropertiesMapper">
|
||||
<resultMap id="BaseResultMap" type="kohgylw.kiftd.server.model.Propertie">
|
||||
<id column="propertie_key" jdbcType="VARCHAR" property="propertieKey" />
|
||||
<result column="propertie_value" jdbcType="VARCHAR" property="propertieValue" />
|
||||
</resultMap>
|
||||
|
||||
<insert id="insert" parameterType="kohgylw.kiftd.server.model.Propertie">
|
||||
INSERT INTO PROPERTIES
|
||||
VALUES(#{propertieKey,jdbcType=VARCHAR},#{propertieValue,jdbcType=VARCHAR})
|
||||
</insert>
|
||||
|
||||
<update id="update" parameterType="kohgylw.kiftd.server.model.Propertie">
|
||||
UPDATE PROPERTIES SET propertie_value =
|
||||
#{propertieValue,jdbcType=VARCHAR} WHERE propertie_key =
|
||||
#{propertieKey,jdbcType=VARCHAR}
|
||||
</update>
|
||||
|
||||
<delete id="deleteByKey" parameterType="java.lang.String">
|
||||
DELETE FROM PROPERTIES WHERE
|
||||
propertie_key = #{propertieKey,jdbcType=VARCHAR}
|
||||
</delete>
|
||||
|
||||
<select id="selectByKey" parameterType="java.lang.String"
|
||||
resultMap="BaseResultMap">
|
||||
SELECT * FROM PROPERTIES WHERE propertie_key =
|
||||
#{propertieKey,jdbcType=VARCHAR}
|
||||
</select>
|
||||
</mapper>
|
@ -13,48 +13,53 @@ import org.springframework.core.io.*;
|
||||
/**
|
||||
*
|
||||
* <h2>服务器部分数据接入设置</h2>
|
||||
* <p>该配置类定义了服务器组件使用的MyBatis将如何链接数据库。如需更换其他数据库,请在此配置自己的数据源并替换原有数据源。</p>
|
||||
* <p>
|
||||
* 该配置类定义了服务器组件使用的MyBatis将如何链接数据库。如需更换其他数据库,请在此配置自己的数据源并替换原有数据源。
|
||||
* </p>
|
||||
*
|
||||
* @author 青阳龙野(kohgylw)
|
||||
* @version 1.0
|
||||
*/
|
||||
@Configurable
|
||||
public class DataAccess
|
||||
{
|
||||
private static Resource[] mapperFiles;
|
||||
private static Resource mybatisConfg;
|
||||
|
||||
@Bean
|
||||
public DataSource dataSource() {
|
||||
final DriverManagerDataSource ds = new DriverManagerDataSource();
|
||||
ds.setDriverClassName(ConfigureReader.instance().getFileNodePathDriver());
|
||||
ds.setUrl(ConfigureReader.instance().getFileNodePathURL());
|
||||
ds.setUsername(ConfigureReader.instance().getFileNodePathUserName());
|
||||
ds.setPassword(ConfigureReader.instance().getFileNodePathPassWord());
|
||||
return (DataSource)ds;
|
||||
}
|
||||
|
||||
@Bean(name = { "sqlSessionFactory" })
|
||||
@Autowired
|
||||
public SqlSessionFactoryBean sqlSessionFactoryBean(final DataSource ds) {
|
||||
final SqlSessionFactoryBean ssf = new SqlSessionFactoryBean();
|
||||
ssf.setDataSource(ds);
|
||||
ssf.setConfigLocation(DataAccess.mybatisConfg);
|
||||
ssf.setMapperLocations(DataAccess.mapperFiles);
|
||||
return ssf;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public MapperScannerConfigurer mapperScannerConfigurer() {
|
||||
final MapperScannerConfigurer msf = new MapperScannerConfigurer();
|
||||
msf.setBasePackage("kohgylw.kiftd.server.mapper");
|
||||
msf.setSqlSessionFactoryBeanName("sqlSessionFactory");
|
||||
return msf;
|
||||
}
|
||||
|
||||
static {
|
||||
final String mybatisResourceFolder = ConfigureReader.instance().getPath() + File.separator + "mybatisResource" + File.separator;
|
||||
final String mapperFilesFolder = mybatisResourceFolder + "mapperXML" + File.separator;
|
||||
DataAccess.mapperFiles = new Resource[] { new FileSystemResource(mapperFilesFolder + "NodeMapper.xml"), new FileSystemResource(mapperFilesFolder + "FolderMapper.xml") };
|
||||
DataAccess.mybatisConfg = (Resource)new FileSystemResource(mybatisResourceFolder + "mybatis.xml");
|
||||
}
|
||||
public class DataAccess {
|
||||
private static Resource[] mapperFiles;
|
||||
private static Resource mybatisConfg;
|
||||
|
||||
@Bean
|
||||
public DataSource dataSource() {
|
||||
final DriverManagerDataSource ds = new DriverManagerDataSource();
|
||||
ds.setDriverClassName(ConfigureReader.instance().getFileNodePathDriver());
|
||||
ds.setUrl(ConfigureReader.instance().getFileNodePathURL());
|
||||
ds.setUsername(ConfigureReader.instance().getFileNodePathUserName());
|
||||
ds.setPassword(ConfigureReader.instance().getFileNodePathPassWord());
|
||||
return (DataSource) ds;
|
||||
}
|
||||
|
||||
@Bean(name = { "sqlSessionFactory" })
|
||||
@Autowired
|
||||
public SqlSessionFactoryBean sqlSessionFactoryBean(final DataSource ds) {
|
||||
final SqlSessionFactoryBean ssf = new SqlSessionFactoryBean();
|
||||
ssf.setDataSource(ds);
|
||||
ssf.setConfigLocation(DataAccess.mybatisConfg);
|
||||
ssf.setMapperLocations(DataAccess.mapperFiles);
|
||||
return ssf;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public MapperScannerConfigurer mapperScannerConfigurer() {
|
||||
final MapperScannerConfigurer msf = new MapperScannerConfigurer();
|
||||
msf.setBasePackage("kohgylw.kiftd.server.mapper");
|
||||
msf.setSqlSessionFactoryBeanName("sqlSessionFactory");
|
||||
return msf;
|
||||
}
|
||||
|
||||
static {
|
||||
final String mybatisResourceFolder = ConfigureReader.instance().getPath() + File.separator + "mybatisResource"
|
||||
+ File.separator;
|
||||
final String mapperFilesFolder = mybatisResourceFolder + "mapperXML" + File.separator;
|
||||
DataAccess.mapperFiles = new Resource[] { new FileSystemResource(mapperFilesFolder + "NodeMapper.xml"),
|
||||
new FileSystemResource(mapperFilesFolder + "FolderMapper.xml"),
|
||||
new FileSystemResource(mapperFilesFolder + "PropertiesMapper.xml") };
|
||||
DataAccess.mybatisConfg = (Resource) new FileSystemResource(mybatisResourceFolder + "mybatis.xml");
|
||||
}
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ public class ExternalLinksController {
|
||||
|
||||
@RequestMapping("/chain/{fileName}")
|
||||
public void chain(HttpServletRequest request,HttpServletResponse response) {
|
||||
fcs.getResourceBychain(request, response);
|
||||
fcs.getResourceByChainKey(request, response);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -37,6 +37,8 @@ public class HomeController {
|
||||
private ShowPictureService sps;
|
||||
@Resource
|
||||
private PlayAudioService pas;
|
||||
@Resource
|
||||
private FileChainService fcs;
|
||||
|
||||
@RequestMapping({ "/getServerOS.ajax" })
|
||||
@ResponseBody
|
||||
@ -263,18 +265,25 @@ public class HomeController {
|
||||
public String pong(final HttpServletRequest request) {
|
||||
return as.doPong(request);
|
||||
}
|
||||
|
||||
|
||||
// 询问是否开启自由注册新账户功能
|
||||
@RequestMapping(value = { "/askForAllowSignUpOrNot.ajax" }, produces = { CHARSET_BY_AJAX })
|
||||
@ResponseBody
|
||||
public String askForAllowSignUpOrNot(final HttpServletRequest request) {
|
||||
return as.isAllowSignUp();
|
||||
}
|
||||
|
||||
|
||||
// 处理注册新账户请求
|
||||
@RequestMapping(value = { "/doSigUp.ajax" }, produces = { CHARSET_BY_AJAX })
|
||||
@ResponseBody
|
||||
public String doSigUp(final HttpServletRequest request) {
|
||||
return as.doSignUp(request);
|
||||
}
|
||||
|
||||
// 获取永久资源链接的对应ckey
|
||||
@RequestMapping(value = { "/getFileChainKey.ajax" }, produces = { CHARSET_BY_AJAX })
|
||||
@ResponseBody
|
||||
public String getFileChainKey(final HttpServletRequest request) {
|
||||
return fcs.getChainKeyByFid(request);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,15 @@
|
||||
package kohgylw.kiftd.server.mapper;
|
||||
|
||||
import kohgylw.kiftd.server.model.Propertie;
|
||||
|
||||
public interface PropertiesMapper {
|
||||
|
||||
int insert(final Propertie p);
|
||||
|
||||
int deleteByKey(final String propertieKey);
|
||||
|
||||
Propertie selectByKey(final String propertieKey);
|
||||
|
||||
int update(final Propertie p);
|
||||
|
||||
}
|
28
src/main/java/kohgylw/kiftd/server/model/Propertie.java
Normal file
28
src/main/java/kohgylw/kiftd/server/model/Propertie.java
Normal file
@ -0,0 +1,28 @@
|
||||
package kohgylw.kiftd.server.model;
|
||||
|
||||
/**
|
||||
*
|
||||
* <h2>文件系统相关设置项的模型</h2>
|
||||
* <p>该模型用于描述文件系统数据库中的PROPERTIES表。</p>
|
||||
* @author 青阳龙野(kohgylw)
|
||||
* @version 1.0
|
||||
*/
|
||||
public class Propertie {
|
||||
|
||||
private String propertieKey;
|
||||
private String propertieValue;
|
||||
|
||||
public String getPropertieKey() {
|
||||
return propertieKey;
|
||||
}
|
||||
public void setPropertieKey(String propertieKey) {
|
||||
this.propertieKey = propertieKey;
|
||||
}
|
||||
public String getPropertieValue() {
|
||||
return propertieValue;
|
||||
}
|
||||
public void setPropertieValue(String propertieValue) {
|
||||
this.propertieValue = propertieValue;
|
||||
}
|
||||
|
||||
}
|
@ -14,12 +14,22 @@ public interface FileChainService {
|
||||
|
||||
/**
|
||||
*
|
||||
* <h2>根据链接返回资源数据</h2>
|
||||
* <p>该方法将通过永久资源链接返回其指向的数据,并声明其可能的ContentType类型。若未开启永久资源链接功能则返回403。</p>
|
||||
* <h2>根据文件ID获取其永久资源链接的ckey</h2>
|
||||
* <p>该方法用于获取加密的ckey,以便在使用资源链接时声明其指向的文件。</p>
|
||||
* @author 青阳龙野(kohgylw)
|
||||
* @param request javax.servlet.http.HttpServletRequest 请求对象
|
||||
* @return java.lang.String 获取的ckey,若获取失败则返回ERROR
|
||||
*/
|
||||
public String getChainKeyByFid(HttpServletRequest request);
|
||||
|
||||
/**
|
||||
*
|
||||
* <h2>根据链接中的ckey返回对应的资源数据</h2>
|
||||
* <p>该方法将通过永久资源链接返回其ckey指向的文件数据,并声明其可能的ContentType类型。若未开启永久资源链接功能则返回403。</p>
|
||||
* @author 青阳龙野(kohgylw)
|
||||
* @param request javax.servlet.http.HttpServletRequest 请求对象
|
||||
* @param response javax.servlet.http.HttpServletResponse 响应对象
|
||||
*/
|
||||
public void getResourceBychain(HttpServletRequest request,HttpServletResponse response);
|
||||
public void getResourceByChainKey(HttpServletRequest request,HttpServletResponse response);
|
||||
|
||||
}
|
||||
|
@ -9,12 +9,19 @@ import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import kohgylw.kiftd.server.enumeration.AccountAuth;
|
||||
import kohgylw.kiftd.server.mapper.FolderMapper;
|
||||
import kohgylw.kiftd.server.mapper.NodeMapper;
|
||||
import kohgylw.kiftd.server.mapper.PropertiesMapper;
|
||||
import kohgylw.kiftd.server.model.Folder;
|
||||
import kohgylw.kiftd.server.model.Node;
|
||||
import kohgylw.kiftd.server.model.Propertie;
|
||||
import kohgylw.kiftd.server.service.FileChainService;
|
||||
import kohgylw.kiftd.server.util.AESCipher;
|
||||
import kohgylw.kiftd.server.util.ConfigureReader;
|
||||
import kohgylw.kiftd.server.util.ContentTypeMap;
|
||||
import kohgylw.kiftd.server.util.FileBlockUtil;
|
||||
import kohgylw.kiftd.server.util.FolderUtil;
|
||||
import kohgylw.kiftd.server.util.LogUtil;
|
||||
import kohgylw.kiftd.server.util.RangeFileStreamWriter;
|
||||
|
||||
@ -24,39 +31,57 @@ public class FileChainServiceImpl extends RangeFileStreamWriter implements FileC
|
||||
@Resource
|
||||
private NodeMapper nm;
|
||||
@Resource
|
||||
private FolderMapper flm;
|
||||
@Resource
|
||||
private FileBlockUtil fbu;
|
||||
@Resource
|
||||
private ContentTypeMap ctm;
|
||||
@Resource
|
||||
private LogUtil lu;
|
||||
@Resource
|
||||
private AESCipher cipher;
|
||||
@Resource
|
||||
private PropertiesMapper pm;
|
||||
@Resource
|
||||
private FolderUtil fu;
|
||||
|
||||
@Override
|
||||
public void getResourceBychain(HttpServletRequest request, HttpServletResponse response) {
|
||||
public void getResourceByChainKey(HttpServletRequest request, HttpServletResponse response) {
|
||||
int statusCode = 403;
|
||||
if (ConfigureReader.instance().isOpenFileChain()) {
|
||||
final String fId = request.getParameter("fid");
|
||||
final String ckey = request.getParameter("ckey");
|
||||
// 权限凭证有效性并确认其对应的资源
|
||||
if (fId != null) {
|
||||
Node f = this.nm.queryById(fId);
|
||||
if (f != null) {
|
||||
File target = this.fbu.getFileFromBlocks(f);
|
||||
if (target != null && target.isFile()) {
|
||||
String fileName = f.getFileName();
|
||||
String suffix = "";
|
||||
if (fileName.indexOf(".") >= 0) {
|
||||
suffix = fileName.substring(fileName.indexOf("."));
|
||||
if (ckey != null) {
|
||||
Propertie keyProp = pm.selectByKey("chain_aes_key");
|
||||
if (keyProp != null) {
|
||||
try {
|
||||
String fid = cipher.decrypt(keyProp.getPropertieValue(), ckey);
|
||||
Node f = this.nm.queryById(fid);
|
||||
if (f != null) {
|
||||
File target = this.fbu.getFileFromBlocks(f);
|
||||
if (target != null && target.isFile()) {
|
||||
String fileName = f.getFileName();
|
||||
String suffix = "";
|
||||
if (fileName.indexOf(".") >= 0) {
|
||||
suffix = fileName.substring(fileName.indexOf("."));
|
||||
}
|
||||
writeRangeFileStream(request, response, target, f.getFileName(),
|
||||
ctm.getContentType(suffix));
|
||||
if (request.getHeader("Range") == null) {
|
||||
this.lu.writeChainEvent(request, f);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
writeRangeFileStream(request, response, target, f.getFileName(), ctm.getContentType(suffix));
|
||||
if (request.getHeader("Range") == null) {
|
||||
this.lu.writeChainEvent(request, f);
|
||||
}
|
||||
return;
|
||||
statusCode = 404;
|
||||
} catch (Exception e) {
|
||||
lu.writeException(e);
|
||||
statusCode = 500;
|
||||
}
|
||||
} else {
|
||||
statusCode = 404;
|
||||
}
|
||||
statusCode = 404;
|
||||
}
|
||||
} else {
|
||||
statusCode = 403;
|
||||
}
|
||||
try {
|
||||
// 处理无法下载的资源
|
||||
@ -66,4 +91,41 @@ public class FileChainServiceImpl extends RangeFileStreamWriter implements FileC
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getChainKeyByFid(HttpServletRequest request) {
|
||||
if (ConfigureReader.instance().isOpenFileChain()) {
|
||||
String fid = request.getParameter("fid");
|
||||
String account = (String) request.getSession().getAttribute("ACCOUNT");
|
||||
if (fid != null) {
|
||||
final Node f = this.nm.queryById(fid);
|
||||
if (f != null) {
|
||||
if (ConfigureReader.instance().authorized(account, AccountAuth.DOWNLOAD_FILES,
|
||||
fu.getAllFoldersId(f.getFileParentFolder()))) {
|
||||
Folder folder = flm.queryById(f.getFileParentFolder());
|
||||
if (ConfigureReader.instance().accessFolder(folder, account)) {
|
||||
// 将指定的fid加密为ckey并返回。
|
||||
try {
|
||||
Propertie keyProp = pm.selectByKey("chain_aes_key");
|
||||
if (keyProp == null) {// 如果没有生成过永久性AES密钥,则先生成再加密
|
||||
String aesKey = cipher.generateRandomKey();
|
||||
Propertie chainAESKey = new Propertie();
|
||||
chainAESKey.setPropertieKey("chain_aes_key");
|
||||
chainAESKey.setPropertieValue(aesKey);
|
||||
if (pm.insert(chainAESKey) > 0) {
|
||||
return cipher.encrypt(aesKey, fid);
|
||||
}
|
||||
} else {// 如果已经有了,则直接用其加密
|
||||
return cipher.encrypt(keyProp.getPropertieValue(), fid);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
lu.writeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return "ERROR";
|
||||
}
|
||||
|
||||
}
|
||||
|
78
src/main/java/kohgylw/kiftd/server/util/AESCipher.java
Normal file
78
src/main/java/kohgylw/kiftd/server/util/AESCipher.java
Normal file
@ -0,0 +1,78 @@
|
||||
package kohgylw.kiftd.server.util;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Base64;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
*
|
||||
* <h2>AES加密器</h2>
|
||||
* <p>该加密器负责对字符串进行加密、解密和随机密码生产操作,详见其中的各个方法注释。</p>
|
||||
* @author 青阳龙野(kohgylw)
|
||||
* @version 1.0
|
||||
*/
|
||||
@Component
|
||||
public class AESCipher {
|
||||
|
||||
private static final String CIPHER_TYPE = "AES";//所用到的加密算法类型
|
||||
private Base64.Encoder encoder;
|
||||
private Base64.Decoder decoder;
|
||||
|
||||
public AESCipher() {
|
||||
encoder = Base64.getEncoder();
|
||||
decoder = Base64.getDecoder();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* <h2>生成随机AES密钥</h2>
|
||||
* <p>该方法将生成一个随机的AES密钥,并转化为Base64字符串返回。</p>
|
||||
* @author 青阳龙野(kohgylw)
|
||||
* @return java.lang.String 随机生成的密钥,以Base64字符串输出
|
||||
*/
|
||||
public String generateRandomKey() throws NoSuchAlgorithmException {
|
||||
KeyGenerator kg = KeyGenerator.getInstance(CIPHER_TYPE);
|
||||
kg.init(128);
|
||||
return encoder.encodeToString(kg.generateKey().getEncoded());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* <h2>对字符串进行AES加密</h2>
|
||||
* <p>该方法用于对传入的字符串进行加密,并以Base64的形式返回加密后的密文。加密用到的密钥也需以Base64的形式传入。</p>
|
||||
* @author 青阳龙野(kohgylw)
|
||||
* @param base64Key java.lang.String 加密密钥,必须以Base64形式传入
|
||||
* @param content java.lang.String 需要加密的内容
|
||||
* @return java.lang.String 加密后的密文,以Base64的形式返回
|
||||
*/
|
||||
public String encrypt(String base64Key, String content) throws Exception {
|
||||
SecretKey key = new SecretKeySpec(decoder.decode(base64Key), CIPHER_TYPE);
|
||||
Cipher cipher = Cipher.getInstance(CIPHER_TYPE);
|
||||
cipher.init(Cipher.ENCRYPT_MODE, key);
|
||||
return encoder.encodeToString(cipher.doFinal(content.getBytes(StandardCharsets.UTF_8)));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* <h2>对密文进行AES解密</h2>
|
||||
* <p>该方法用于对传入的Base64形式的密文进行解密。解密用到的密钥也需以Base64的形式传入。</p>
|
||||
* @author 青阳龙野(kohgylw)
|
||||
* @param base64Key java.lang.String 解密密钥,必须以Base64形式传入
|
||||
* @param ciphertext java.lang.String 需要解密的密文,必须以Base64形式传入
|
||||
* @return java.lang.String 解密后的内容
|
||||
*/
|
||||
public String decrypt(String base64Key, String ciphertext) throws Exception {
|
||||
SecretKey key = new SecretKeySpec(decoder.decode(base64Key), CIPHER_TYPE);
|
||||
Cipher cipher = Cipher.getInstance(CIPHER_TYPE);
|
||||
cipher.init(Cipher.DECRYPT_MODE, key);
|
||||
return new String(cipher.doFinal(decoder.decode(ciphertext)),StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
}
|
@ -81,15 +81,20 @@ public class FileNodeUtil {
|
||||
ResultSet indexCount = state4.executeQuery("SHOW INDEX FROM FILE WHERE Key_name = 'file_index'");
|
||||
if (!indexCount.next()) {
|
||||
final Statement state41 = conn.createStatement();
|
||||
state41.execute("CREATE INDEX file_index ON FILE (file_id,file_name)");
|
||||
state41.execute("CREATE INDEX file_index ON FILE (file_name)");
|
||||
state41.close();
|
||||
}
|
||||
state4.close();
|
||||
} else {
|
||||
final Statement state4 = conn.createStatement();
|
||||
state4.execute("CREATE INDEX IF NOT EXISTS file_index ON FILE (file_id,file_name)");
|
||||
state4.execute("CREATE INDEX IF NOT EXISTS file_index ON FILE (file_name)");
|
||||
state4.close();
|
||||
}
|
||||
// 生成用于持久化保存的、系统自动生成的、和文件系统相关设置项的存储表
|
||||
final Statement state5 = conn.createStatement();
|
||||
state5.execute(
|
||||
"CREATE TABLE IF NOT EXISTS PROPERTIES(propertie_key VARCHAR(128) PRIMARY KEY,propertie_value VARCHAR(128) NOT NULL)");
|
||||
state5.close();
|
||||
}
|
||||
Printer.instance.print("文件节点初始化完毕。");
|
||||
} catch (Exception e) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
#Generated by Maven Integration for Eclipse
|
||||
#Fri Oct 04 16:01:13 CST 2019
|
||||
#Sat Oct 05 11:10:33 CST 2019
|
||||
version=1.0.23-RELEASE
|
||||
groupId=kohgylw
|
||||
m2e.projectName=kiftd
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
target/classes/kohgylw/kiftd/server/model/Propertie.class
Normal file
BIN
target/classes/kohgylw/kiftd/server/model/Propertie.class
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
target/classes/kohgylw/kiftd/server/util/AESCipher.class
Normal file
BIN
target/classes/kohgylw/kiftd/server/util/AESCipher.class
Normal file
Binary file not shown.
Binary file not shown.
@ -800,7 +800,7 @@
|
||||
<textarea id="fileChainTextarea" class="form-control" rows="3" readonly></textarea>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-info" onclick="copyFileChain()">复制链接</button>
|
||||
<button id="copyChainBtn" type="button" class="btn btn-info" onclick="copyFileChain()">复制链接</button>
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -392,7 +392,7 @@ function getServerOS() {
|
||||
url : "homeController/getServerOS.ajax",
|
||||
success : function(result) {
|
||||
if (result == "mustLogin") {
|
||||
window.location.href = "login.html";
|
||||
window.location.href = "prv/login.html";
|
||||
return;
|
||||
}
|
||||
$("#serverOS").text(result);
|
||||
@ -421,7 +421,7 @@ function showFolderView(fid,targetId) {
|
||||
$("#publishTime").html("<span class='graytext'>获取失败,请尝试刷新</span>");
|
||||
$("#parentlistbox").html("<span class='graytext'>获取失败,请尝试刷新</span>");
|
||||
} else if (result == "mustLogin") {
|
||||
window.location.href = "login.html";
|
||||
window.location.href = "prv/login.html";
|
||||
} else if(result == "NOT_FOUND") {
|
||||
document.cookie = "folder_id=" + escape("root");// 归位记忆路径
|
||||
window.location.href="/";
|
||||
@ -1038,7 +1038,7 @@ function createfolder() {
|
||||
url : "homeController/newFolder.ajax",
|
||||
success : function(result) {
|
||||
if (result == "mustLogin") {
|
||||
window.location.href = "login.html";
|
||||
window.location.href = "prv/login.html";
|
||||
} else {
|
||||
if (result == "noAuthorized") {
|
||||
showFolderAlert("提示:您的操作未被授权,创建文件夹失败。");
|
||||
@ -1104,7 +1104,7 @@ function deleteFolder(folderId) {
|
||||
url : "homeController/deleteFolder.ajax",
|
||||
success : function(result) {
|
||||
if (result == "mustLogin") {
|
||||
window.location.href = "login.html";
|
||||
window.location.href = "prv/login.html";
|
||||
} else {
|
||||
if (result == "noAuthorized") {
|
||||
$('#deleteFolderMessage').text("提示:您的操作未被授权,删除文件夹失败");
|
||||
@ -1172,7 +1172,7 @@ function renameFolder(folderId) {
|
||||
url : "homeController/renameFolder.ajax",
|
||||
success : function(result) {
|
||||
if (result == "mustLogin") {
|
||||
window.location.href = "login.html";
|
||||
window.location.href = "prv/login.html";
|
||||
} else {
|
||||
if (result == "noAuthorized") {
|
||||
showRFolderAlert("提示:您的操作未被授权,编辑失败。");
|
||||
@ -1287,7 +1287,7 @@ function checkUploadFile() {
|
||||
url : "homeController/checkUploadFile.ajax",
|
||||
success : function(result) {
|
||||
if (result == "mustLogin") {
|
||||
window.location.href = "login.html";
|
||||
window.location.href = "prv/login.html";
|
||||
} else {
|
||||
if (result == "errorParameter") {
|
||||
showUploadFileAlert("提示:参数不正确,无法开始上传");
|
||||
@ -1541,7 +1541,7 @@ function deleteFile(fileId) {
|
||||
url : "homeController/deleteFile.ajax",
|
||||
success : function(result) {
|
||||
if (result == "mustLogin") {
|
||||
window.location.href = "login.html";
|
||||
window.location.href = "prv/login.html";
|
||||
} else {
|
||||
if (result == "noAuthorized") {
|
||||
$('#deleteFileMessage').text("提示:您的操作未被授权,删除失败");
|
||||
@ -1598,7 +1598,7 @@ function renameFile(fileId) {
|
||||
url : "homeController/renameFile.ajax",
|
||||
success : function(result) {
|
||||
if (result == "mustLogin") {
|
||||
window.location.href = "login.html";
|
||||
window.location.href = "prv/login.html";
|
||||
} else {
|
||||
if (result == "cannotRenameFile") {
|
||||
showRFileAlert("提示:出现意外错误,可能未能重命名文件,请刷新后重试。");
|
||||
@ -1992,7 +1992,7 @@ function deleteAllChecked() {
|
||||
url : "homeController/deleteCheckedFiles.ajax",
|
||||
success : function(result) {
|
||||
if (result == "mustLogin") {
|
||||
window.location.href = "login.html";
|
||||
window.location.href = "prv/login.html";
|
||||
} else {
|
||||
if (result == "noAuthorized") {
|
||||
$('#deleteFileMessage').text("提示:您的操作未被授权,删除失败");
|
||||
@ -2259,7 +2259,7 @@ function doMoveFiles(){
|
||||
url : "homeController/confirmMoveFiles.ajax",
|
||||
success : function(result) {
|
||||
if (result == "mustLogin") {
|
||||
window.location.href = "login.html";
|
||||
window.location.href = "prv/login.html";
|
||||
} else {
|
||||
if (result == "noAuthorized") {
|
||||
$('#moveFilesMessage').text("提示:您的操作未被授权,移动失败");
|
||||
@ -2353,7 +2353,7 @@ function sendMoveFilesReq(){
|
||||
url : "homeController/moveCheckedFiles.ajax",
|
||||
success : function(result) {
|
||||
if (result == "mustLogin") {
|
||||
window.location.href = "login.html";
|
||||
window.location.href = "prv/login.html";
|
||||
} else {
|
||||
if (result == "noAuthorized") {
|
||||
$('#moveFilesMessage').text("提示:您的操作未被授权,移动失败");
|
||||
@ -2455,7 +2455,7 @@ function selectInCompletePath(keyworld){
|
||||
$("#publishTime").html("<span class='graytext'>获取失败,请尝试刷新</span>");
|
||||
$("#parentlistbox").html("<span class='graytext'>获取失败,请尝试刷新</span>");
|
||||
} else if (result == "mustLogin") {
|
||||
window.location.href = "login.html";
|
||||
window.location.href = "prv/login.html";
|
||||
} else if(result == "notAccess"){
|
||||
document.cookie = "folder_id=" + escape("root");
|
||||
window.location.href="/";
|
||||
@ -2630,7 +2630,7 @@ function checkImportFolder(){
|
||||
showImportFolderAlert("提示:参数不正确,无法开始上传");
|
||||
break;
|
||||
case 'mustLogin':
|
||||
window.location.href = "login.html";
|
||||
window.location.href = "prv/login.html";
|
||||
break;
|
||||
case 'fileOverSize':
|
||||
showImportFolderAlert("提示:文件["+ifs[maxFileIndex].webkitRelativePath+"]的体积超过最大限制("+resJson.maxSize+"),无法开始上传");
|
||||
@ -2962,11 +2962,37 @@ function changePasswordGetNewVerCode(){
|
||||
$("#changepassword_showvercode").attr("src","homeController/getNewVerCode.do?s="+(new Date()).getTime());
|
||||
}
|
||||
|
||||
// 显示永久资源链接
|
||||
// 获取永久资源链接
|
||||
function getFileChain(fileId,fileName){
|
||||
var getChainFileName=fileName.replace("#","%23").replace("%","%25").replace("?","%3F");
|
||||
$("#fileChainTextarea").text(encodeURI(window.location.protocol+"//"+window.location.host+"/externalLinksController/chain/"+getChainFileName+"?fid="+fileId));
|
||||
$("#fileChainTextarea").text("正在获取……");
|
||||
$("#copyChainBtn").attr('disabled', true);
|
||||
$('#fileChainModal').modal('show');
|
||||
$.ajax({
|
||||
type : "POST",
|
||||
dataType : "text",
|
||||
url : "homeController/getFileChainKey.ajax",
|
||||
data : {
|
||||
fid : fileId
|
||||
},
|
||||
success : function(result) {
|
||||
switch (result) {
|
||||
case "ERROR":
|
||||
$("#fileChainTextarea").text("提示:获取失败,请刷新页面或稍后再试。");
|
||||
break;
|
||||
case "mustlogin":
|
||||
window.location.href = "prv/login.html";
|
||||
break;
|
||||
default:
|
||||
var getChainFileName=fileName.replace("#","%23").replace("%","%25").replace("?","%3F");
|
||||
$("#fileChainTextarea").text(encodeURI(window.location.protocol+"//"+window.location.host+"/externalLinksController/chain/"+getChainFileName+"?ckey=")+encodeURIComponent(result));
|
||||
$("#copyChainBtn").attr('disabled', false);
|
||||
break;
|
||||
}
|
||||
},
|
||||
error : function() {
|
||||
$("#fileChainTextarea").text("提示:获取失败,无法连接服务器。");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 复制链接内容
|
||||
@ -2975,14 +3001,12 @@ function copyFileChain(){
|
||||
let issafariBrowser = /Safari/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent);
|
||||
if(issafariBrowser){
|
||||
node.setSelectionRange(0, 9999);
|
||||
}
|
||||
else{
|
||||
}else{
|
||||
const range = document.createRange();
|
||||
range.selectNode(node);
|
||||
const selection = window.getSelection();
|
||||
if(selection.rangeCount > 0) selection.removeAllRanges();
|
||||
selection.addRange(range);
|
||||
}
|
||||
|
||||
document.execCommand('copy');
|
||||
}
|
6
webContext/js/home.min.js
vendored
6
webContext/js/home.min.js
vendored
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user