package com.jspxcms.core.web.back;
import static com.jspxcms.core.support.Constants.CREATE;
import static com.jspxcms.core.support.Constants.DELETE_SUCCESS;
import static com.jspxcms.core.support.Constants.EDIT;
import static com.jspxcms.core.support.Constants.MESSAGE;
import static com.jspxcms.core.support.Constants.OPERATION_FAILURE;
import static com.jspxcms.core.support.Constants.OPERATION_SUCCESS;
import static com.jspxcms.core.support.Constants.OPRT;
import static com.jspxcms.core.support.Constants.SAVE_SUCCESS;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.List;
import java.util.Properties;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import com.jspxcms.common.util.AntZipUtils;
import com.jspxcms.common.web.PathResolver;
import com.jspxcms.common.web.Servlets;
import com.jspxcms.core.domain.Site;
import com.jspxcms.core.support.Constants;
import com.jspxcms.core.support.Context;
import com.jspxcms.core.support.ForeContext;
import com.jspxcms.core.support.WebFile;
/**
* WebFileController
*
* @author liufang
*
*/
@Controller
@RequestMapping("/core/web_file")
public class WebFileController {
private static final Logger logger = LoggerFactory
.getLogger(WebFileController.class);
private static FileFilter dirFilter = new FileFilter() {
public boolean accept(File pathname) {
return pathname.isDirectory();
}
};
@RequiresPermissions("core:web_file:left")
@RequestMapping("left.do")
public String left(Boolean isSiteFile, HttpServletRequest request,
HttpServletResponse response, org.springframework.ui.Model modelMap)
throws IOException {
Site site = Context.getCurrentSite(request);
if (isSiteFile == null) {
isSiteFile = false;
}
File rootFile = new File(pathResolver.getPath(""));
File parentFile;
if (isSiteFile) {
parentFile = rootFile;
} else {
parentFile = new File(pathResolver.getPath(site
.getFilesBasePath("")));
modelMap.addAttribute("theme", site.getTemplateTheme());
}
WebFile parentWebFile = new WebFile(parentFile,
rootFile.getCanonicalPath(), request.getContextPath());
if (!hasPermission(parentFile, site)) {
response.sendError(HttpServletResponse.SC_FORBIDDEN);
return null;
}
List<WebFile> list = parentWebFile.listFiles(dirFilter);
modelMap.addAttribute("isEnableSiteFile", isEnableSiteFile());
modelMap.addAttribute("isSiteFile", isSiteFile);
modelMap.addAttribute("parent", parentWebFile);
modelMap.addAttribute("list", list);
return "core/web_file/web_file_left";
}
@RequiresPermissions("core:web_file:left_tree")
@RequestMapping("left_tree.do")
public String leftTree(HttpServletRequest request,
HttpServletResponse response, org.springframework.ui.Model modelMap)
throws IOException {
Site site = Context.getCurrentSite(request);
File rootFile = new File(pathResolver.getPath(""));
File parentFile = rootFile;
String parentId = Servlets.getParameter(request, "parentId");
if (StringUtils.isNotBlank(parentId)) {
parentFile = new File(pathResolver.getPath(parentId));
}
WebFile parentWebFile = new WebFile(parentFile,
rootFile.getCanonicalPath(), request.getContextPath());
if (!hasPermission(parentFile, site)) {
response.sendError(HttpServletResponse.SC_FORBIDDEN);
return null;
}
List<WebFile> list = parentWebFile.listFiles(dirFilter);
modelMap.addAttribute("list", list);
return "core/web_file/web_file_left_tree";
}
@RequiresPermissions("core:web_file:list")
@RequestMapping("list.do")
public String list(HttpServletRequest request,
HttpServletResponse response, org.springframework.ui.Model modelMap)
throws IOException {
String parentId = Servlets.getParameter(request, "parentId");
Site site = Context.getCurrentSite(request);
File root = new File(pathResolver.getPath(""));
String base = site.getFilesBasePath("");
if (StringUtils.isBlank(parentId)) {
parentId = base;
}
String realPath = pathResolver.getPath(parentId);
File parent = new File(realPath);
if (!hasPermission(parent, site)) {
response.sendError(HttpServletResponse.SC_FORBIDDEN);
return null;
}
WebFile parentWebFile = new WebFile(parent, root.getAbsolutePath(),
request.getContextPath());
String searchName = Servlets.getParameter(request, "search_name");
List<WebFile> list = parentWebFile.listFiles(searchName);
String sort = request.getParameter("page_sort");
String sortDir = request.getParameter("page_sort_dir");
WebFile.sort(list, sort, sortDir);
if (parentId.length() > 1) {
WebFile ppWebFile = parentWebFile.getParentFile();
ppWebFile.setParent(true);
list.add(0, ppWebFile);
modelMap.addAttribute("ppId", ppWebFile.getId());
}
modelMap.addAttribute("parentId", parentId);
modelMap.addAttribute("list", list);
return "core/web_file/web_file_list";
}
@RequiresPermissions("core:web_file:create")
@RequestMapping("create.do")
public String create(HttpServletRequest request,
HttpServletResponse response, org.springframework.ui.Model modelMap) {
String parentId = Servlets.getParameter(request, "parentId");
Site site = Context.getCurrentSite(request);
File root = new File(pathResolver.getPath(""));
String base = site.getFilesBasePath("");
if (StringUtils.isBlank(parentId)) {
parentId = base;
}
String cid = Servlets.getParameter(request, "cid");
if (StringUtils.isNotBlank(cid)) {
File file = new File(pathResolver.getPath(cid));
WebFile bean = new WebFile(file, root.getAbsolutePath(),
request.getContextPath());
modelMap.addAttribute("bean", bean);
}
modelMap.addAttribute("parentId", parentId);
modelMap.addAttribute(OPRT, CREATE);
return "core/web_file/web_file_form";
}
@RequiresPermissions("core:web_file:edit")
@RequestMapping("edit.do")
public String edit(HttpServletRequest request,
HttpServletResponse response, org.springframework.ui.Model modelMap)
throws IOException {
Site site = Context.getCurrentSite(request);
String parentId = Servlets.getParameter(request, "parentId");
String id = Servlets.getParameter(request, "id");
File root = new File(pathResolver.getPath(""));
File file = new File(pathResolver.getPath(id));
if (!hasPermission(file, site)) {
response.sendError(HttpServletResponse.SC_FORBIDDEN);
return null;
}
WebFile bean = new WebFile(file, root.getAbsolutePath(),
request.getContextPath());
modelMap.addAttribute("parentId", parentId);
modelMap.addAttribute("bean", bean);
modelMap.addAttribute(OPRT, EDIT);
return "core/web_file/web_file_form";
}
@RequiresPermissions("core:web_file:mkdir")
@RequestMapping(value = "mkdir.do", method = RequestMethod.POST)
public String mkdir(String parentId, String dir,
HttpServletRequest request, HttpServletResponse response,
RedirectAttributes ra) throws IOException {
Site site = Context.getCurrentSite(request);
String base = site.getFilesBasePath("");
if (StringUtils.isBlank(parentId)) {
parentId = base;
}
File parent = new File(pathResolver.getPath(parentId));
File newDir = new File(parent, dir);
if (!hasPermission(newDir, site)) {
response.sendError(HttpServletResponse.SC_FORBIDDEN);
return null;
}
boolean isSuccess = newDir.mkdir();
ra.addFlashAttribute("refreshLeft", true);
ra.addAttribute("parentId", parentId);
ra.addFlashAttribute(MESSAGE, isSuccess ? OPERATION_SUCCESS
: OPERATION_FAILURE);
return "redirect:list.do";
}
@RequiresPermissions("core:web_file:save")
@RequestMapping(value = "save.do", method = RequestMethod.POST)
public String save(String parentId, String name, String text,
String redirect, HttpServletRequest request,
HttpServletResponse response, RedirectAttributes ra)
throws IOException {
Site site = Context.getCurrentSite(request);
File parent = new File(pathResolver.getPath(parentId));
File file = new File(parent, name);
if (!hasPermission(file, site)) {
response.sendError(HttpServletResponse.SC_FORBIDDEN);
return null;
}
try {
FileUtils.write(file, text, "UTF-8");
} catch (IOException e) {
logger.error("", e);
}
logger.info("save file, name={}.", file.getAbsolutePath());
ra.addFlashAttribute("refreshLeft", true);
ra.addAttribute("parentId", parentId);
ra.addFlashAttribute(MESSAGE, SAVE_SUCCESS);
if (Constants.REDIRECT_LIST.equals(redirect)) {
return "redirect:list.do";
} else if (Constants.REDIRECT_CREATE.equals(redirect)) {
return "redirect:create.do";
} else {
File root = new File(pathResolver.getPath(""));
WebFile webFile = new WebFile(file, root.getAbsolutePath(),
request.getContextPath());
ra.addAttribute("id", webFile.getId());
return "redirect:edit.do";
}
}
@RequiresPermissions("core:web_file:update")
@RequestMapping(value = "update.do", method = RequestMethod.POST)
public void update(String parentId, String origName, String name,
String text, Integer position, String redirect,
HttpServletRequest request, HttpServletResponse response)
throws IOException {
Site site = Context.getCurrentSite(request);
File root = new File(pathResolver.getPath(""));
File parent = new File(pathResolver.getPath(parentId));
if (!hasPermission(parent, site)) {
response.sendError(HttpServletResponse.SC_FORBIDDEN);
return;
}
File origFile = new File(parent, origName);
File destFile = new File(parent, name);
WebFile origWebFile = new WebFile(origFile, root.getAbsolutePath());
if (origWebFile.isEditable()) {
FileUtils.write(origFile, text, "UTF-8");
}
if (!origName.equals(name)) {
FileUtils.moveFile(origFile, destFile);
}
logger.info("update file, name={}.", origFile.getAbsolutePath());
Servlets.writeHtml(response, "true");
}
@RequiresPermissions("core:web_file:delete")
@RequestMapping("delete.do")
public String delete(HttpServletRequest request,
HttpServletResponse response, RedirectAttributes ra)
throws IOException {
Site site = Context.getCurrentSite(request);
String parentId = Servlets.getParameter(request, "parentId");
String[] ids = Servlets.getParameterValues(request, "ids");
if (ArrayUtils.isNotEmpty(ids)) {
for (int i = 0, len = ids.length; i < len; i++) {
File f = new File(pathResolver.getPath(ids[i]));
if (!hasPermission(f, site)) {
response.sendError(HttpServletResponse.SC_FORBIDDEN);
return null;
}
boolean isSuccess = FileUtils.deleteQuietly(f);
if (isSuccess) {
logger.info("delete file success, name={}.",
f.getAbsolutePath());
} else {
logger.info("delete file failure, name={}.",
f.getAbsolutePath());
}
}
}
ra.addAttribute("parentId", parentId);
ra.addFlashAttribute("refreshLeft", true);
ra.addFlashAttribute(MESSAGE, DELETE_SUCCESS);
return "redirect:list.do";
}
@RequiresPermissions("core:web_file:rename")
@RequestMapping("rename.do")
public String rename(HttpServletRequest request,
HttpServletResponse response, RedirectAttributes ra)
throws IOException {
String parentId = Servlets.getParameter(request, "parentId");
Site site = Context.getCurrentSite(request);
String base = site.getFilesBasePath("");
if (StringUtils.isBlank(parentId)) {
parentId = base;
}
String id = Servlets.getParameter(request, "id");
String name = Servlets.getParameter(request, "name");
File file = new File(pathResolver.getPath(id));
if (!hasPermission(file, site)) {
response.sendError(HttpServletResponse.SC_FORBIDDEN);
return null;
}
file.renameTo(new File(file.getParentFile(), name));
ra.addAttribute("parentId", parentId);
ra.addFlashAttribute("refreshLeft", true);
ra.addFlashAttribute(MESSAGE, OPERATION_SUCCESS);
return "redirect:list.do";
}
@RequiresPermissions("core:web_file:move")
@RequestMapping("move.do")
public String move(HttpServletRequest request,
HttpServletResponse response, RedirectAttributes ra)
throws IOException {
String parentId = Servlets.getParameter(request, "parentId");
Site site = Context.getCurrentSite(request);
String base = site.getFilesBasePath("");
if (StringUtils.isBlank(parentId)) {
parentId = base;
}
String[] ids = Servlets.getParameterValues(request, "ids");
String dest = Servlets.getParameter(request, "dest");
File destDir = new File(pathResolver.getPath(dest));
String destPath = destDir.getAbsolutePath();
String path, parentPath;
for (String id : ids) {
File file = new File(pathResolver.getPath(id));
path = file.getAbsolutePath();
parentPath = file.getParentFile().getAbsolutePath();
if (destPath.equals(path) || destPath.equals(parentPath)
|| destPath.startsWith(path + File.separator)) {
continue;
}
if (!hasPermission(file, site)) {
response.sendError(HttpServletResponse.SC_FORBIDDEN);
return null;
}
if (!hasPermission(destDir, site)) {
response.sendError(HttpServletResponse.SC_FORBIDDEN);
return null;
}
FileUtils.moveToDirectory(file, destDir, true);
}
ra.addAttribute("refreshLeft", true);
ra.addAttribute("parentId", parentId);
ra.addFlashAttribute("refreshLeft", true);
ra.addFlashAttribute(MESSAGE, OPERATION_SUCCESS);
return "redirect:list.do";
}
@RequiresPermissions("core:web_file:zip")
@RequestMapping("zip.do")
public String zip(HttpServletRequest request, HttpServletResponse response,
RedirectAttributes ra) throws IOException {
Site site = Context.getCurrentSite(request);
String parentId = Servlets.getParameter(request, "parentId");
String[] ids = Servlets.getParameterValues(request, "ids");
File[] files = new File[ids.length];
for (int i = 0, len = ids.length; i < len; i++) {
files[i] = new File(pathResolver.getPath(ids[i]));
if (!hasPermission(files[i], site)) {
response.sendError(HttpServletResponse.SC_FORBIDDEN);
return null;
}
}
AntZipUtils.zip(files);
ra.addAttribute("parentId", parentId);
ra.addFlashAttribute("refreshLeft", true);
ra.addFlashAttribute(MESSAGE, OPERATION_SUCCESS);
return "redirect:list.do";
}
@RequiresPermissions("core:web_file:zip_download")
@RequestMapping("zip_download.do")
public void zipDownload(HttpServletRequest request,
HttpServletResponse response, RedirectAttributes ra)
throws IOException {
Site site = Context.getCurrentSite(request);
String[] ids = Servlets.getParameterValues(request, "ids");
File[] files = new File[ids.length];
for (int i = 0, len = ids.length; i < len; i++) {
files[i] = new File(pathResolver.getPath(ids[i]));
if (!hasPermission(files[i], site)) {
response.sendError(HttpServletResponse.SC_FORBIDDEN);
return;
}
}
response.setContentType("application/x-download;charset=UTF-8");
response.addHeader("Content-disposition", "filename=zip-download.zip");
try {
AntZipUtils.zip(files, response.getOutputStream());
} catch (IOException e) {
logger.error("zip error!", e);
}
}
@RequiresPermissions("core:web_file:unzip")
@RequestMapping("unzip.do")
public String unzip(HttpServletRequest request,
HttpServletResponse response, RedirectAttributes ra)
throws IOException {
String parentId = Servlets.getParameter(request, "parentId");
Site site = Context.getCurrentSite(request);
String base = site.getFilesBasePath("");
if (StringUtils.isBlank(parentId)) {
parentId = base;
}
String[] ids = Servlets.getParameterValues(request, "ids");
for (String id : ids) {
File file = new File(pathResolver.getPath(id));
if (!hasPermission(file, site)) {
response.sendError(HttpServletResponse.SC_FORBIDDEN);
return null;
}
if (AntZipUtils.isZipFile(file)) {
AntZipUtils.unzip(file, file.getParentFile());
}
}
ra.addAttribute("parentId", parentId);
ra.addFlashAttribute("refreshLeft", true);
ra.addFlashAttribute(MESSAGE, OPERATION_SUCCESS);
return "redirect:list.do";
}
@RequiresPermissions("core:web_file:upload")
@RequestMapping("upload.do")
public void upload(
@RequestParam(value = "file", required = false) MultipartFile file,
HttpServletRequest request, HttpServletResponse response)
throws IllegalStateException, IOException {
String parentId = Servlets.getParameter(request, "parentId");
Site site = Context.getCurrentSite(request);
String base = site.getFilesBasePath("");
if (StringUtils.isBlank(parentId)) {
parentId = base;
}
File dest = new File(pathResolver.getPath(parentId),
file.getOriginalFilename());
if (!hasPermission(dest, site)) {
response.sendError(HttpServletResponse.SC_FORBIDDEN);
return;
}
file.transferTo(dest);
Servlets.writeHtml(response, "true");
}
@RequiresPermissions("core:web_file:zip_upload")
@RequestMapping("zip_upload.do")
public String zipUpload(
@RequestParam(value = "file", required = false) MultipartFile file,
HttpServletRequest request, HttpServletResponse response,
RedirectAttributes ra) throws IOException {
String parentId = Servlets.getParameter(request, "parentId");
Site site = Context.getCurrentSite(request);
String base = site.getFilesBasePath("");
if (StringUtils.isBlank(parentId)) {
parentId = base;
}
File parentFile = new File(pathResolver.getPath(parentId));
if (!hasPermission(parentFile, site)) {
response.sendError(HttpServletResponse.SC_FORBIDDEN);
return null;
}
File tempFile = File.createTempFile(
String.valueOf(System.currentTimeMillis()), "temp");
file.transferTo(tempFile);
AntZipUtils.unzip(tempFile, parentFile);
tempFile.delete();
ra.addAttribute("parentId", parentId);
ra.addFlashAttribute("refreshLeft", true);
ra.addFlashAttribute(MESSAGE, OPERATION_SUCCESS);
return "redirect:list.do";
}
private boolean hasPermission(File file, Site site) throws IOException {
String realPath = file.getCanonicalPath();
String baseRealPath = pathResolver.getPath("");
// 去除最后一个'/'
baseRealPath = baseRealPath.substring(0, baseRealPath.length() - 1);
String templateRealPath = pathResolver.getPath(ForeContext.FILES_PATH
+ "/" + site.getId());
logger.debug("realPath: {}", realPath);
logger.debug("baseRealPath: {}", baseRealPath);
logger.debug("templateRealPath: {}", templateRealPath);
// 不能访问应用以外的文件
if (!realPath.startsWith(baseRealPath)) {
return false;
}
// 在模板路径下的文件可以访问
if (realPath.startsWith(templateRealPath)) {
return true;
}
Subject subject = SecurityUtils.getSubject();
// 开启站点文件并且有权限的,可以访问。
if (isEnableSiteFile()
&& subject.isPermitted("core:web_file:site_file")) {
return true;
} else {
return false;
}
}
private boolean isEnableSiteFile() {
String isEnableSiteFile = properties
.getProperty("webFile.isEnableSiteFile");
return "true".equals(isEnableSiteFile);
}
@Autowired
@Qualifier("main")
private Properties properties;
@Autowired
private PathResolver pathResolver;
}