mirror of https://github.com/halo-dev/halo
👽 代码优化
parent
42e37e95f3
commit
a1e7d80cc8
12
pom.xml
12
pom.xml
|
@ -131,18 +131,6 @@
|
||||||
<version>${commons-lang3.version}</version>
|
<version>${commons-lang3.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.jsoup</groupId>
|
|
||||||
<artifactId>jsoup</artifactId>
|
|
||||||
<version>1.9.2</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.google.guava</groupId>
|
|
||||||
<artifactId>guava</artifactId>
|
|
||||||
<version>18.0</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-devtools</artifactId>
|
<artifactId>spring-boot-devtools</artifactId>
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
package cc.ryanc.halo.config;
|
|
||||||
|
|
||||||
import cc.ryanc.halo.security.XssFilter;
|
|
||||||
import com.google.common.collect.Maps;
|
|
||||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author : RYAN0UP
|
|
||||||
* @version : 1.0
|
|
||||||
* @date : 2018/5/4
|
|
||||||
*/
|
|
||||||
@Configuration
|
|
||||||
public class XssConfig {
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public FilterRegistrationBean xssFilterRegistrationBean() {
|
|
||||||
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
|
|
||||||
filterRegistrationBean.setFilter(new XssFilter());
|
|
||||||
filterRegistrationBean.setOrder(1);
|
|
||||||
filterRegistrationBean.setEnabled(true);
|
|
||||||
filterRegistrationBean.addUrlPatterns("/*");
|
|
||||||
Map<String, String> initParameters = Maps.newHashMap();
|
|
||||||
//后台不做拦截请求
|
|
||||||
initParameters.put("excludes", "/admin/*");
|
|
||||||
initParameters.put("isIncludeRichText", "true");
|
|
||||||
filterRegistrationBean.setInitParameters(initParameters);
|
|
||||||
return filterRegistrationBean;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,32 +0,0 @@
|
||||||
package cc.ryanc.halo.security;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.jsoup.Jsoup;
|
|
||||||
import org.jsoup.nodes.Document;
|
|
||||||
import org.jsoup.safety.Whitelist;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author : RYAN0UP
|
|
||||||
* @version : 1.0
|
|
||||||
* @date : 2018/5/4
|
|
||||||
*/
|
|
||||||
public class JsoupUtil {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 白名单
|
|
||||||
*/
|
|
||||||
private static final Whitelist whitelist = Whitelist.basicWithImages();
|
|
||||||
|
|
||||||
private static final Document.OutputSettings outputSettings = new Document.OutputSettings().prettyPrint(false);
|
|
||||||
|
|
||||||
static {
|
|
||||||
whitelist.addAttributes(":all", "style");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String clean(String content) {
|
|
||||||
if (StringUtils.isNotBlank(content)) {
|
|
||||||
content = content.trim();
|
|
||||||
}
|
|
||||||
return Jsoup.clean(content, "", whitelist, outputSettings);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,77 +0,0 @@
|
||||||
package cc.ryanc.halo.security;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.BooleanUtils;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
|
|
||||||
import javax.servlet.*;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author : RYAN0UP
|
|
||||||
* @version : 1.0
|
|
||||||
* @date : 2018/5/4
|
|
||||||
*/
|
|
||||||
public class XssFilter implements Filter {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否过滤富文本内容
|
|
||||||
*/
|
|
||||||
private static boolean IS_INCLUDE_RICH_TEXT = false;
|
|
||||||
|
|
||||||
private List<String> excludes = new ArrayList<>();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
|
|
||||||
HttpServletRequest req = (HttpServletRequest) request;
|
|
||||||
HttpServletResponse resp = (HttpServletResponse) response;
|
|
||||||
if (handleExcludeURL(req, resp)) {
|
|
||||||
filterChain.doFilter(request, response);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper((HttpServletRequest) request, IS_INCLUDE_RICH_TEXT);
|
|
||||||
filterChain.doFilter(xssRequest, response);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean handleExcludeURL(HttpServletRequest request, HttpServletResponse response) {
|
|
||||||
|
|
||||||
if (excludes == null || excludes.isEmpty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
String url = request.getServletPath();
|
|
||||||
for (String pattern : excludes) {
|
|
||||||
Pattern p = Pattern.compile("^" + pattern);
|
|
||||||
Matcher m = p.matcher(url);
|
|
||||||
if (m.find()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init(FilterConfig filterConfig) throws ServletException {
|
|
||||||
String isIncludeRichText = filterConfig.getInitParameter("isIncludeRichText");
|
|
||||||
if (StringUtils.isNotBlank(isIncludeRichText)) {
|
|
||||||
IS_INCLUDE_RICH_TEXT = BooleanUtils.toBoolean(isIncludeRichText);
|
|
||||||
}
|
|
||||||
String temp = filterConfig.getInitParameter("excludes");
|
|
||||||
if (temp != null) {
|
|
||||||
String[] url = temp.split(",");
|
|
||||||
for (int i = 0; url != null && i < url.length; i++) {
|
|
||||||
excludes.add(url[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void destroy() {
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,81 +0,0 @@
|
||||||
package cc.ryanc.halo.security;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletRequestWrapper;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author : RYAN0UP
|
|
||||||
* @version : 1.0
|
|
||||||
* @date : 2018/5/4
|
|
||||||
*/
|
|
||||||
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
|
|
||||||
|
|
||||||
HttpServletRequest orgRequest = null;
|
|
||||||
private boolean isIncludeRichText = false;
|
|
||||||
|
|
||||||
public XssHttpServletRequestWrapper(HttpServletRequest request, boolean isIncludeRichText) {
|
|
||||||
super(request);
|
|
||||||
orgRequest = request;
|
|
||||||
this.isIncludeRichText = isIncludeRichText;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取最原始的request的静态方法
|
|
||||||
*
|
|
||||||
* @param req req
|
|
||||||
* @return HttpServletRequest
|
|
||||||
*/
|
|
||||||
public static HttpServletRequest getOrgRequest(HttpServletRequest req) {
|
|
||||||
if (req instanceof XssHttpServletRequestWrapper) {
|
|
||||||
return ((XssHttpServletRequestWrapper) req).getOrgRequest();
|
|
||||||
}
|
|
||||||
|
|
||||||
return req;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getParameter(String name) {
|
|
||||||
Boolean flag = ("content".equals(name) || name.endsWith("WithHtml"));
|
|
||||||
if (flag && !isIncludeRichText) {
|
|
||||||
return super.getParameter(name);
|
|
||||||
}
|
|
||||||
name = JsoupUtil.clean(name);
|
|
||||||
String value = super.getParameter(name);
|
|
||||||
if (StringUtils.isNotBlank(value)) {
|
|
||||||
value = JsoupUtil.clean(value);
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String[] getParameterValues(String name) {
|
|
||||||
String[] arr = super.getParameterValues(name);
|
|
||||||
if (arr != null) {
|
|
||||||
for (int i = 0; i < arr.length; i++) {
|
|
||||||
arr[i] = JsoupUtil.clean(arr[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return arr;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getHeader(String name) {
|
|
||||||
name = JsoupUtil.clean(name);
|
|
||||||
String value = super.getHeader(name);
|
|
||||||
if (StringUtils.isNotBlank(value)) {
|
|
||||||
value = JsoupUtil.clean(value);
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取最原始的request
|
|
||||||
*
|
|
||||||
* @return HttpServletRequest
|
|
||||||
*/
|
|
||||||
public HttpServletRequest getOrgRequest() {
|
|
||||||
return orgRequest;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -196,40 +196,6 @@ public class HaloUtils {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 移除文件
|
|
||||||
*
|
|
||||||
* @param fileName fileName
|
|
||||||
* @return true or false
|
|
||||||
*/
|
|
||||||
public static boolean removeFile(String fileName){
|
|
||||||
File file = new File(fileName);
|
|
||||||
if(file.exists() && file.delete()){
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 移除非空文件夹
|
|
||||||
*
|
|
||||||
* @param dir dir
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
public static boolean removeDir(File dir) {
|
|
||||||
if (dir.isDirectory()) {
|
|
||||||
String[] children = dir.list();
|
|
||||||
for (int i=0; i<children.length; i++) {
|
|
||||||
boolean success = removeDir(new File(dir, children[i]));
|
|
||||||
if (!success) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 目录此时为空,可以删除
|
|
||||||
return dir.delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取当前时间
|
* 获取当前时间
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,167 +0,0 @@
|
||||||
package cc.ryanc.halo.utils;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
import java.io.*;
|
|
||||||
import java.util.Enumeration;
|
|
||||||
import java.util.zip.ZipEntry;
|
|
||||||
import java.util.zip.ZipFile;
|
|
||||||
import java.util.zip.ZipOutputStream;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author : RYAN0UP
|
|
||||||
* @version : 1.0
|
|
||||||
* @date : 2018/5/11
|
|
||||||
* Zip压缩工具类
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
public class ZipUtils {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 解压Zip文件到指定目录
|
|
||||||
*
|
|
||||||
* @param zipFilePath 压缩文件的路径
|
|
||||||
* @param descDir 解压的路径
|
|
||||||
*/
|
|
||||||
public static void unZip(String zipFilePath,String descDir){
|
|
||||||
File zipFile=new File(zipFilePath);
|
|
||||||
File pathFile=new File(descDir);
|
|
||||||
if(!pathFile.exists()){
|
|
||||||
pathFile.mkdirs();
|
|
||||||
}
|
|
||||||
ZipFile zip=null;
|
|
||||||
InputStream in=null;
|
|
||||||
OutputStream out=null;
|
|
||||||
try {
|
|
||||||
zip=new ZipFile(zipFile);
|
|
||||||
Enumeration<?> entries=zip.entries();
|
|
||||||
while(entries.hasMoreElements()){
|
|
||||||
ZipEntry entry=(ZipEntry) entries.nextElement();
|
|
||||||
String zipEntryName=entry.getName();
|
|
||||||
in=zip.getInputStream(entry);
|
|
||||||
|
|
||||||
String outPath=(descDir+"/"+zipEntryName).replace("\\*", "/");
|
|
||||||
File file=new File(outPath.substring(0, outPath.lastIndexOf('/')));
|
|
||||||
if(!file.exists()){
|
|
||||||
file.mkdirs();
|
|
||||||
}
|
|
||||||
if(new File(outPath).isDirectory()){
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
out=new FileOutputStream(outPath);
|
|
||||||
byte[] buf=new byte[4*1024];
|
|
||||||
int len;
|
|
||||||
while((len=in.read(buf))>=0){
|
|
||||||
out.write(buf, 0, len);
|
|
||||||
}
|
|
||||||
in.close();
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("解压失败:{0}",e.getMessage());
|
|
||||||
}finally{
|
|
||||||
try {
|
|
||||||
if(zip!=null)
|
|
||||||
zip.close();
|
|
||||||
if(in!=null)
|
|
||||||
in.close();
|
|
||||||
if(out!=null)
|
|
||||||
out.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
log.error("未知错误:{0}",e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 压缩目录
|
|
||||||
* https://github.com/otale/tale/blob/master/src/main/java/com/tale/utils/ZipUtils.java
|
|
||||||
*
|
|
||||||
* @param srcFolder 目录路径
|
|
||||||
* @param destZipFile 输出路径
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
public static void zipFolder(String srcFolder, String destZipFile) throws Exception {
|
|
||||||
ZipOutputStream zip = null;
|
|
||||||
FileOutputStream fileWriter = null;
|
|
||||||
|
|
||||||
fileWriter = new FileOutputStream(destZipFile);
|
|
||||||
zip = new ZipOutputStream(fileWriter);
|
|
||||||
|
|
||||||
addFolderToZip("", srcFolder, zip);
|
|
||||||
zip.flush();
|
|
||||||
zip.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 压缩文件
|
|
||||||
* https://github.com/otale/tale/blob/master/src/main/java/com/tale/utils/ZipUtils.java
|
|
||||||
*
|
|
||||||
* @param filePath 文件路径
|
|
||||||
* @param zipPath 输出路径
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
public static void zipFile(String filePath, String zipPath) throws Exception{
|
|
||||||
byte[] buffer = new byte[1024];
|
|
||||||
FileOutputStream fos = new FileOutputStream(zipPath);
|
|
||||||
ZipOutputStream zos = new ZipOutputStream(fos);
|
|
||||||
ZipEntry ze= new ZipEntry("spy.log");
|
|
||||||
zos.putNextEntry(ze);
|
|
||||||
FileInputStream in = new FileInputStream(filePath);
|
|
||||||
int len;
|
|
||||||
while ((len = in.read(buffer)) > 0) {
|
|
||||||
zos.write(buffer, 0, len);
|
|
||||||
}
|
|
||||||
in.close();
|
|
||||||
zos.closeEntry();
|
|
||||||
//remember close it
|
|
||||||
zos.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 添加文件到Zip压缩文件
|
|
||||||
* https://github.com/otale/tale/blob/master/src/main/java/com/tale/utils/ZipUtils.java
|
|
||||||
*
|
|
||||||
* @param path path
|
|
||||||
* @param srcFile srcFile
|
|
||||||
* @param zip zip
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
public static void addFileToZip(String path, String srcFile, ZipOutputStream zip)
|
|
||||||
throws Exception {
|
|
||||||
|
|
||||||
File folder = new File(srcFile);
|
|
||||||
if (folder.isDirectory()) {
|
|
||||||
addFolderToZip(path, srcFile, zip);
|
|
||||||
} else {
|
|
||||||
byte[] buf = new byte[1024];
|
|
||||||
int len;
|
|
||||||
FileInputStream in = new FileInputStream(srcFile);
|
|
||||||
zip.putNextEntry(new ZipEntry(path + "/" + folder.getName()));
|
|
||||||
while ((len = in.read(buf)) > 0) {
|
|
||||||
zip.write(buf, 0, len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 添加目录到zip压缩文件
|
|
||||||
* https://github.com/otale/tale/blob/master/src/main/java/com/tale/utils/ZipUtils.java
|
|
||||||
*
|
|
||||||
* @param path path
|
|
||||||
* @param srcFolder srcFolder
|
|
||||||
* @param zip zip
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
public static void addFolderToZip(String path, String srcFolder, ZipOutputStream zip) throws Exception {
|
|
||||||
File folder = new File(srcFolder);
|
|
||||||
if (null != path && folder.isDirectory()) {
|
|
||||||
for (String fileName : folder.list()) {
|
|
||||||
if ("".equals(path)) {
|
|
||||||
addFileToZip(folder.getName(), srcFolder + "/" + fileName, zip);
|
|
||||||
} else {
|
|
||||||
addFileToZip(path + "/" + folder.getName(), srcFolder + "/" + fileName, zip);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -12,6 +12,7 @@ import cc.ryanc.halo.service.PostService;
|
||||||
import cc.ryanc.halo.service.UserService;
|
import cc.ryanc.halo.service.UserService;
|
||||||
import cc.ryanc.halo.utils.HaloUtils;
|
import cc.ryanc.halo.utils.HaloUtils;
|
||||||
import cc.ryanc.halo.web.controller.core.BaseController;
|
import cc.ryanc.halo.web.controller.core.BaseController;
|
||||||
|
import cn.hutool.core.lang.Validator;
|
||||||
import cn.hutool.crypto.SecureUtil;
|
import cn.hutool.crypto.SecureUtil;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
@ -28,8 +29,6 @@ import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpSession;
|
import javax.servlet.http.HttpSession;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author : RYAN0UP
|
* @author : RYAN0UP
|
||||||
|
@ -126,10 +125,7 @@ public class AdminController extends BaseController {
|
||||||
if (StringUtils.equals(aUser.getLoginEnable(), "false")) {
|
if (StringUtils.equals(aUser.getLoginEnable(), "false")) {
|
||||||
status = "disable";
|
status = "disable";
|
||||||
} else {
|
} else {
|
||||||
//验证是否是邮箱登录
|
if (Validator.isEmail(loginName)) {
|
||||||
Pattern patternEmail = Pattern.compile("\\w[-\\w.+]*@([A-Za-z0-9][-A-Za-z0-9]+\\.)+[A-Za-z]{2,14}");
|
|
||||||
Matcher matcher = patternEmail.matcher(loginName);
|
|
||||||
if (matcher.find()) {
|
|
||||||
user = userService.userLoginByEmail(loginName, SecureUtil.md5(loginPwd)).get(0);
|
user = userService.userLoginByEmail(loginName, SecureUtil.md5(loginPwd)).get(0);
|
||||||
} else {
|
} else {
|
||||||
user = userService.userLoginByName(loginName, SecureUtil.md5(loginPwd)).get(0);
|
user = userService.userLoginByName(loginName, SecureUtil.md5(loginPwd)).get(0);
|
||||||
|
|
|
@ -10,6 +10,7 @@ import cc.ryanc.halo.service.PostService;
|
||||||
import cc.ryanc.halo.service.UserService;
|
import cc.ryanc.halo.service.UserService;
|
||||||
import cc.ryanc.halo.utils.HaloUtils;
|
import cc.ryanc.halo.utils.HaloUtils;
|
||||||
import cc.ryanc.halo.web.controller.core.BaseController;
|
import cc.ryanc.halo.web.controller.core.BaseController;
|
||||||
|
import cn.hutool.core.lang.Validator;
|
||||||
import cn.hutool.crypto.SecureUtil;
|
import cn.hutool.crypto.SecureUtil;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
@ -31,8 +32,6 @@ import javax.websocket.server.PathParam;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author : RYAN0UP
|
* @author : RYAN0UP
|
||||||
|
@ -110,18 +109,16 @@ public class CommentController extends BaseController{
|
||||||
*/
|
*/
|
||||||
@GetMapping("/revert")
|
@GetMapping("/revert")
|
||||||
public String moveToPublish(@PathParam("commentId") Long commentId,
|
public String moveToPublish(@PathParam("commentId") Long commentId,
|
||||||
@PathParam("status") Integer status){
|
@PathParam("status") Integer status,
|
||||||
|
HttpSession session){
|
||||||
Comment comment = commentService.updateCommentStatus(commentId,0);
|
Comment comment = commentService.updateCommentStatus(commentId,0);
|
||||||
Post post = comment.getPost();
|
Post post = comment.getPost();
|
||||||
|
User user = (User) session.getAttribute(HaloConst.USER_SESSION_KEY);
|
||||||
//判断评论者的邮箱是否符合规则
|
|
||||||
Pattern patternEmail = Pattern.compile("\\w[-\\w.+]*@([A-Za-z0-9][-A-Za-z0-9]+\\.)+[A-Za-z]{2,14}");
|
|
||||||
Matcher matcher = patternEmail.matcher(comment.getCommentAuthorEmail());
|
|
||||||
|
|
||||||
//判断是否启用邮件服务
|
//判断是否启用邮件服务
|
||||||
if(StringUtils.equals(HaloConst.OPTIONS.get("smtp_email_enable"),"true") && StringUtils.equals(HaloConst.OPTIONS.get("comment_pass_notice"),"true")) {
|
if(StringUtils.equals(HaloConst.OPTIONS.get("smtp_email_enable"),"true") && StringUtils.equals(HaloConst.OPTIONS.get("comment_pass_notice"),"true")) {
|
||||||
try {
|
try {
|
||||||
if (status == 1 && matcher.find()) {
|
if (status == 1 && Validator.isEmail(comment.getCommentAuthorEmail())) {
|
||||||
Map<String, Object> map = new HashMap<>();
|
Map<String, Object> map = new HashMap<>();
|
||||||
if (StringUtils.equals(post.getPostType(), HaloConst.POST_TYPE_POST)) {
|
if (StringUtils.equals(post.getPostType(), HaloConst.POST_TYPE_POST)) {
|
||||||
map.put("pageUrl", HaloConst.OPTIONS.get("blog_url") + "/archives/" + post.getPostUrl() + "#comment-id-" + comment.getCommentId());
|
map.put("pageUrl", HaloConst.OPTIONS.get("blog_url") + "/archives/" + post.getPostUrl() + "#comment-id-" + comment.getCommentId());
|
||||||
|
@ -132,7 +129,7 @@ public class CommentController extends BaseController{
|
||||||
map.put("commentContent", comment.getCommentContent());
|
map.put("commentContent", comment.getCommentContent());
|
||||||
map.put("blogUrl", HaloConst.OPTIONS.get("blog_url"));
|
map.put("blogUrl", HaloConst.OPTIONS.get("blog_url"));
|
||||||
map.put("blogTitle", HaloConst.OPTIONS.get("blog_title"));
|
map.put("blogTitle", HaloConst.OPTIONS.get("blog_title"));
|
||||||
map.put("author", userService.findUser().getUserDisplayName());
|
map.put("author", user.getUserDisplayName());
|
||||||
mailService.sendTemplateMail(
|
mailService.sendTemplateMail(
|
||||||
comment.getCommentAuthorEmail(),
|
comment.getCommentAuthorEmail(),
|
||||||
"您在" + HaloConst.OPTIONS.get("blog_title") + "的评论已审核通过!", map, "common/mail/mail_passed.ftl");
|
"您在" + HaloConst.OPTIONS.get("blog_title") + "的评论已审核通过!", map, "common/mail/mail_passed.ftl");
|
||||||
|
@ -198,7 +195,7 @@ public class CommentController extends BaseController{
|
||||||
comment.setCommentAuthorEmail(user.getUserEmail());
|
comment.setCommentAuthorEmail(user.getUserEmail());
|
||||||
comment.setCommentAuthorUrl(HaloConst.OPTIONS.get("blog_url"));
|
comment.setCommentAuthorUrl(HaloConst.OPTIONS.get("blog_url"));
|
||||||
comment.setCommentAuthorIp(HaloUtils.getIpAddr(request));
|
comment.setCommentAuthorIp(HaloUtils.getIpAddr(request));
|
||||||
comment.setCommentAuthorAvatarMd5(SecureUtil.md5(userService.findUser().getUserEmail()));
|
comment.setCommentAuthorAvatarMd5(SecureUtil.md5(user.getUserEmail()));
|
||||||
comment.setCommentDate(new Date());
|
comment.setCommentDate(new Date());
|
||||||
String lastContent = " //<a href='#comment-id-"+lastComment.getCommentId()+"'>@"+lastComment.getCommentAuthor()+"</a>:"+lastComment.getCommentContent();
|
String lastContent = " //<a href='#comment-id-"+lastComment.getCommentId()+"'>@"+lastComment.getCommentAuthor()+"</a>:"+lastComment.getCommentContent();
|
||||||
comment.setCommentContent(commentContent+lastContent);
|
comment.setCommentContent(commentContent+lastContent);
|
||||||
|
@ -208,13 +205,9 @@ public class CommentController extends BaseController{
|
||||||
comment.setIsAdmin(1);
|
comment.setIsAdmin(1);
|
||||||
commentService.saveByComment(comment);
|
commentService.saveByComment(comment);
|
||||||
|
|
||||||
//正则表达式判断对方的邮箱是否是正确的格式
|
|
||||||
Pattern patternEmail = Pattern.compile("\\w[-\\w.+]*@([A-Za-z0-9][-A-Za-z0-9]+\\.)+[A-Za-z]{2,14}");
|
|
||||||
Matcher matcher = patternEmail.matcher(lastComment.getCommentAuthorEmail());
|
|
||||||
|
|
||||||
//邮件通知
|
//邮件通知
|
||||||
if(StringUtils.equals(HaloConst.OPTIONS.get("smtp_email_enable"),"true") && StringUtils.equals(HaloConst.OPTIONS.get("comment_reply_notice"),"true")) {
|
if(StringUtils.equals(HaloConst.OPTIONS.get("smtp_email_enable"),"true") && StringUtils.equals(HaloConst.OPTIONS.get("comment_reply_notice"),"true")) {
|
||||||
if(matcher.find()){
|
if(Validator.isEmail(lastComment.getCommentAuthorEmail())){
|
||||||
Map<String, Object> map = new HashMap<>();
|
Map<String, Object> map = new HashMap<>();
|
||||||
map.put("blogTitle",HaloConst.OPTIONS.get("blog_title"));
|
map.put("blogTitle",HaloConst.OPTIONS.get("blog_title"));
|
||||||
map.put("commentAuthor",lastComment.getCommentAuthor());
|
map.put("commentAuthor",lastComment.getCommentAuthor());
|
||||||
|
|
|
@ -11,7 +11,6 @@ import cc.ryanc.halo.service.TagService;
|
||||||
import cc.ryanc.halo.utils.HaloUtils;
|
import cc.ryanc.halo.utils.HaloUtils;
|
||||||
import cc.ryanc.halo.web.controller.core.BaseController;
|
import cc.ryanc.halo.web.controller.core.BaseController;
|
||||||
import cn.hutool.http.HtmlUtil;
|
import cn.hutool.http.HtmlUtil;
|
||||||
import lombok.Value;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
|
@ -7,8 +7,9 @@ import cc.ryanc.halo.model.dto.LogsRecord;
|
||||||
import cc.ryanc.halo.service.LogsService;
|
import cc.ryanc.halo.service.LogsService;
|
||||||
import cc.ryanc.halo.service.OptionsService;
|
import cc.ryanc.halo.service.OptionsService;
|
||||||
import cc.ryanc.halo.utils.HaloUtils;
|
import cc.ryanc.halo.utils.HaloUtils;
|
||||||
import cc.ryanc.halo.utils.ZipUtils;
|
|
||||||
import cc.ryanc.halo.web.controller.core.BaseController;
|
import cc.ryanc.halo.web.controller.core.BaseController;
|
||||||
|
import cn.hutool.core.io.FileUtil;
|
||||||
|
import cn.hutool.core.util.ZipUtil;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
@ -106,8 +107,8 @@ public class ThemeController extends BaseController {
|
||||||
logsService.saveByLogs(
|
logsService.saveByLogs(
|
||||||
new Logs(LogsRecord.UPLOAD_THEME, file.getOriginalFilename(), HaloUtils.getIpAddr(request), new Date())
|
new Logs(LogsRecord.UPLOAD_THEME, file.getOriginalFilename(), HaloUtils.getIpAddr(request), new Date())
|
||||||
);
|
);
|
||||||
ZipUtils.unZip(themePath.getAbsolutePath(), new File(basePath.getAbsolutePath(), "templates/themes/").getAbsolutePath());
|
ZipUtil.unzip(themePath,new File(basePath.getAbsolutePath(), "templates/themes/"));
|
||||||
HaloUtils.removeFile(themePath.getAbsolutePath());
|
FileUtil.del(themePath);
|
||||||
HaloConst.THEMES.clear();
|
HaloConst.THEMES.clear();
|
||||||
HaloConst.THEMES = HaloUtils.getThemes();
|
HaloConst.THEMES = HaloUtils.getThemes();
|
||||||
} else {
|
} else {
|
||||||
|
@ -132,7 +133,7 @@ public class ThemeController extends BaseController {
|
||||||
try {
|
try {
|
||||||
File basePath = new File(ResourceUtils.getURL("classpath:").getPath());
|
File basePath = new File(ResourceUtils.getURL("classpath:").getPath());
|
||||||
File themePath = new File(basePath.getAbsolutePath(), "templates/themes/" + themeName);
|
File themePath = new File(basePath.getAbsolutePath(), "templates/themes/" + themeName);
|
||||||
HaloUtils.removeDir(themePath);
|
FileUtil.del(themePath);
|
||||||
HaloConst.THEMES.clear();
|
HaloConst.THEMES.clear();
|
||||||
HaloConst.THEMES = HaloUtils.getThemes();
|
HaloConst.THEMES = HaloUtils.getThemes();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
|
@ -10,6 +10,7 @@ import cc.ryanc.halo.service.PostService;
|
||||||
import cc.ryanc.halo.service.UserService;
|
import cc.ryanc.halo.service.UserService;
|
||||||
import cc.ryanc.halo.utils.HaloUtils;
|
import cc.ryanc.halo.utils.HaloUtils;
|
||||||
import cn.hutool.core.util.URLUtil;
|
import cn.hutool.core.util.URLUtil;
|
||||||
|
import cn.hutool.http.HtmlUtil;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
@ -98,15 +99,19 @@ public class FrontCommentController {
|
||||||
try{
|
try{
|
||||||
Comment lastComment = null;
|
Comment lastComment = null;
|
||||||
post = postService.findByPostId(post.getPostId()).get();
|
post = postService.findByPostId(post.getPostId()).get();
|
||||||
comment.setCommentAuthorEmail(comment.getCommentAuthorEmail().toLowerCase());
|
comment.setCommentAuthorEmail(HtmlUtil.encode(comment.getCommentAuthorEmail()).toLowerCase());
|
||||||
comment.setPost(post);
|
comment.setPost(post);
|
||||||
comment.setCommentDate(new Date());
|
comment.setCommentDate(new Date());
|
||||||
comment.setCommentAuthorIp(HaloUtils.getIpAddr(request));
|
comment.setCommentAuthorIp(HaloUtils.getIpAddr(request));
|
||||||
comment.setIsAdmin(0);
|
comment.setIsAdmin(0);
|
||||||
|
comment.setCommentAuthor(HtmlUtil.encode(comment.getCommentAuthor()));
|
||||||
if(comment.getCommentParent()>0){
|
if(comment.getCommentParent()>0){
|
||||||
lastComment = commentService.findCommentById(comment.getCommentParent()).get();
|
lastComment = commentService.findCommentById(comment.getCommentParent()).get();
|
||||||
String lastContent = " //<a href='#comment-id-"+lastComment.getCommentId()+"'>@"+lastComment.getCommentAuthor()+"</a>:"+lastComment.getCommentContent();
|
String lastContent = " //<a href='#comment-id-"+lastComment.getCommentId()+"'>@"+lastComment.getCommentAuthor()+"</a>:"+lastComment.getCommentContent();
|
||||||
comment.setCommentContent(StringUtils.substringAfter(comment.getCommentContent(),":")+lastContent);
|
comment.setCommentContent(StringUtils.substringAfter(HtmlUtil.encode(comment.getCommentContent()),":")+lastContent);
|
||||||
|
}else{
|
||||||
|
//将评论内容的字符专为安全字符
|
||||||
|
comment.setCommentContent(HtmlUtil.encode(comment.getCommentContent()));
|
||||||
}
|
}
|
||||||
if(StringUtils.isNotEmpty(comment.getCommentAuthorUrl())){
|
if(StringUtils.isNotEmpty(comment.getCommentAuthorUrl())){
|
||||||
comment.setCommentAuthorUrl(URLUtil.formatUrl(comment.getCommentAuthorUrl()));
|
comment.setCommentAuthorUrl(URLUtil.formatUrl(comment.getCommentAuthorUrl()));
|
||||||
|
|
|
@ -62,7 +62,7 @@
|
||||||
<#switch comment.commentStatus>
|
<#switch comment.commentStatus>
|
||||||
<#case 0>
|
<#case 0>
|
||||||
<button class="btn btn-primary btn-xs " onclick="replyShow('${comment.commentId?c}','${comment.post.postId?c}')" <#if comment.isAdmin==1>disabled</#if>>回复</button>
|
<button class="btn btn-primary btn-xs " onclick="replyShow('${comment.commentId?c}','${comment.post.postId?c}')" <#if comment.isAdmin==1>disabled</#if>>回复</button>
|
||||||
<button class="btn btn-danger btn-xs " onclick="modelShow('/admin/comments/throw?commentId=${comment.commentId?c}&status=1','确定移动到回收站?')">丢弃</button>
|
<button class="btn btn-danger btn-xs " onclick="modelShow('/admin/comments/throw?commentId=${comment.commentId?c}&status=0','确定移动到回收站?')">丢弃</button>
|
||||||
<#break >
|
<#break >
|
||||||
<#case 1>
|
<#case 1>
|
||||||
<a data-pjax="true" class="btn btn-primary btn-xs " href="/admin/comments/revert?commentId=${comment.commentId?c}&status=1">通过</a>
|
<a data-pjax="true" class="btn btn-primary btn-xs " href="/admin/comments/revert?commentId=${comment.commentId?c}&status=1">通过</a>
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
<p>一款使用Java开发的简约,"轻",快的博客系统。</p>
|
<p>一款使用Java开发的简约,"轻",快的博客系统。</p>
|
||||||
<p>非常感谢你使用Halo进行创作。</p>
|
<p>非常感谢你使用Halo进行创作。</p>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
<p>目前该博客系统为beta测试版,有可能会出现一些莫名奇妙的bug,所以希望各位在使用过程中及时向我反馈:</p>
|
<p>如果在使用过程中出现bug或者无法解决的问题,希望各位在使用过程中及时向我反馈:</p>
|
||||||
<p>Github issues :<a href='https://github.com/ruibaby/halo' target="_blank">https://github.com/ruibaby/halo</a></p>
|
<p>Github issues :<a href='https://github.com/ruibaby/halo' target="_blank">https://github.com/ruibaby/halo</a></p>
|
||||||
<p>Blog : <a href="https://ryanc.cc" target="_blank">https://ryanc.cc</a> </p>
|
<p>Blog : <a href="https://ryanc.cc" target="_blank">https://ryanc.cc</a> </p>
|
||||||
<p>Email : <a href='mailto:i@ryanc.cc'>i@ryanc.cc</a></p>
|
<p>Email : <a href='mailto:i@ryanc.cc'>i@ryanc.cc</a></p>
|
||||||
|
|
|
@ -52,17 +52,32 @@
|
||||||
首页
|
首页
|
||||||
<#break >
|
<#break >
|
||||||
<#case "post.ftl">
|
<#case "post.ftl">
|
||||||
文章内容
|
文章页面
|
||||||
<#break >
|
<#break >
|
||||||
<#case "archives.ftl">
|
<#case "archives.ftl">
|
||||||
文章归档
|
文章归档页面
|
||||||
<#break >
|
<#break >
|
||||||
<#case "links.ftl">
|
<#case "links.ftl">
|
||||||
友情链接
|
友情链接页面
|
||||||
<#break >
|
<#break >
|
||||||
<#case "module/macro.ftl">
|
<#case "module/macro.ftl">
|
||||||
宏模板
|
宏模板
|
||||||
<#break >
|
<#break >
|
||||||
|
<#case "tag.ftl">
|
||||||
|
单个标签页面
|
||||||
|
<#break >
|
||||||
|
<#case "tags.ftl">
|
||||||
|
标签列表页面
|
||||||
|
<#break>
|
||||||
|
<#case "category.ftl">
|
||||||
|
单个分类页面
|
||||||
|
<#break >
|
||||||
|
<#case "page.ftl">
|
||||||
|
自定义页面
|
||||||
|
<#break>
|
||||||
|
<#case "gallery.ftl">
|
||||||
|
图库页面
|
||||||
|
<#break>
|
||||||
</#switch>
|
</#switch>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
@ -146,6 +146,7 @@
|
||||||
dropZoneTitle: '拖拽主题压缩包到这里 …<br>不支持多个主题同时上传',
|
dropZoneTitle: '拖拽主题压缩包到这里 …<br>不支持多个主题同时上传',
|
||||||
showClose: false
|
showClose: false
|
||||||
}).on("fileuploaded",function (event,data,previewId,index) {
|
}).on("fileuploaded",function (event,data,previewId,index) {
|
||||||
|
var data = data.jqXHR.responseJSON;
|
||||||
if(data.code==1){
|
if(data.code==1){
|
||||||
$("#uploadForm").hide(400);
|
$("#uploadForm").hide(400);
|
||||||
$.toast({
|
$.toast({
|
||||||
|
|
|
@ -12,6 +12,6 @@ public class DemoUtilTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testZip(){
|
public void testZip(){
|
||||||
ZipUtils.unZip("/Users/ryan0up/Desktop/adminlog.html.zip","/Users/ryan0up/Desktop/");
|
//ZipUtils.unZip("/Users/ryan0up/Desktop/adminlog.html.zip","/Users/ryan0up/Desktop/");
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue