1
2
3
4
5
6
7
8
9
10
11 package psiprobe.controllers.deploy;
12
13 import com.google.common.base.Strings;
14
15 import jakarta.servlet.http.HttpServletRequest;
16 import jakarta.servlet.http.HttpServletResponse;
17
18 import java.io.File;
19 import java.io.IOException;
20 import java.nio.file.Files;
21 import java.nio.file.Path;
22 import java.util.ArrayList;
23 import java.util.HashMap;
24 import java.util.List;
25 import java.util.Map;
26
27 import org.apache.catalina.Context;
28 import org.apache.commons.io.FileUtils;
29 import org.apache.commons.io.FilenameUtils;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32 import org.springframework.beans.factory.annotation.Value;
33 import org.springframework.security.core.Authentication;
34 import org.springframework.security.core.context.SecurityContextHolder;
35 import org.springframework.stereotype.Controller;
36 import org.springframework.web.bind.annotation.GetMapping;
37 import org.springframework.web.bind.annotation.PostMapping;
38 import org.springframework.web.bind.annotation.RequestParam;
39 import org.springframework.web.multipart.MultipartFile;
40 import org.springframework.web.servlet.ModelAndView;
41 import org.springframework.web.servlet.view.InternalResourceView;
42
43 import psiprobe.controllers.AbstractTomcatContainerController;
44
45
46
47
48 @Controller
49 public class CopySingleFileController extends AbstractTomcatContainerController {
50
51
52 private static final Logger logger = LoggerFactory.getLogger(CopySingleFileController.class);
53
54 @GetMapping("/adm/deployfile.htm")
55 @Override
56 public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
57 throws Exception {
58 return super.handleRequest(request, response);
59 }
60
61 @Override
62 protected ModelAndView handleRequestInternal(HttpServletRequest request,
63 HttpServletResponse response) throws Exception {
64 return new ModelAndView(new InternalResourceView(getViewName()));
65 }
66
67 @PostMapping("/adm/deployfile.htm")
68 public ModelAndView handleFileUpload(@RequestParam("file") MultipartFile file,
69 @RequestParam("context") String contextName, @RequestParam("where") String where,
70 @RequestParam(value = "reload", required = false) String reloadParam,
71 @RequestParam(value = "discard", required = false) String discardParam,
72 HttpServletRequest request) throws IOException {
73
74 List<Context> apps;
75 try {
76 apps = containerWrapper.getTomcatContainer().findContexts();
77 } catch (NullPointerException ex) {
78 throw new IllegalStateException(
79 "No container found for your server: " + getServletContext().getServerInfo(), ex);
80 }
81
82 List<Map<String, String>> applications = new ArrayList<>();
83 for (Context appContext : apps) {
84
85 if (!Strings.isNullOrEmpty(appContext.getName())) {
86 Map<String, String> app = new HashMap<>();
87 app.put("value", appContext.getName());
88 app.put("label", appContext.getName());
89 applications.add(app);
90 }
91 }
92 request.setAttribute("apps", applications);
93
94 String errMsg = null;
95
96
97 if (file == null || file.isEmpty()) {
98 errMsg = getMessageSourceAccessor().getMessage("probe.src.deploy.file.notFile.failure")
99 + " [null or empty]";
100 request.setAttribute("errorMessage", errMsg);
101 return new ModelAndView(new InternalResourceView(getViewName()));
102 }
103
104
105 Path tmpPath = null;
106 try {
107 String fileName = file.getOriginalFilename();
108 if (!Strings.isNullOrEmpty(fileName)) {
109 fileName = FilenameUtils.getName(fileName);
110 tmpPath = Path.of(System.getProperty("java.io.tmpdir"), fileName);
111 file.transferTo(tmpPath);
112 } else {
113 errMsg = getMessageSourceAccessor().getMessage("probe.src.deploy.file.notFile.failure")
114 + " [null or empty]";
115 request.setAttribute("errorMessage", errMsg);
116 return new ModelAndView(new InternalResourceView(getViewName()));
117 }
118 } catch (IOException e) {
119 logger.error("Could not process file upload", e);
120 request.setAttribute("errorMessage", getMessageSourceAccessor()
121 .getMessage("probe.src.deploy.file.uploadfailure", new Object[] {e.getMessage()}));
122
123 Files.delete(tmpPath);
124 return new ModelAndView(new InternalResourceView(getViewName()));
125 }
126
127 try {
128 contextName = containerWrapper.getTomcatContainer().formatContextName(contextName);
129
130
131
132
133
134 String visibleContextName = contextName.isEmpty() ? "/" : contextName;
135 request.setAttribute("contextName", visibleContextName);
136
137
138 if (containerWrapper.getTomcatContainer().findContext(contextName) != null) {
139
140 File destFile = Path
141 .of(containerWrapper.getTomcatContainer().getAppBase().getPath(), contextName + where)
142 .toFile();
143
144
145 if (destFile.exists()) {
146 if (!destFile.getAbsolutePath().contains("..")) {
147
148 FileUtils.copyFileToDirectory(tmpPath.toFile(), destFile);
149
150 request.setAttribute("successFile", Boolean.TRUE);
151
152 Authentication auth = SecurityContextHolder.getContext().getAuthentication();
153
154 String name = auth.getName();
155 if (contextName.matches("\\w*")) {
156 logger.info(getMessageSourceAccessor().getMessage("probe.src.log.copyfile"), name,
157 contextName);
158 }
159 Context context = containerWrapper.getTomcatContainer().findContext(contextName);
160
161 if ("yes".equalsIgnoreCase(discardParam)) {
162 containerWrapper.getTomcatContainer().discardWorkDir(context);
163 if (contextName.matches("\\w*")) {
164 logger.info(getMessageSourceAccessor().getMessage("probe.src.log.discardwork"),
165 name, contextName);
166 }
167 }
168
169 if ("yes".equalsIgnoreCase(reloadParam) && context != null) {
170 context.reload();
171 request.setAttribute("reloadContext", Boolean.TRUE);
172 if (contextName.matches("\\w*")) {
173 logger.info(getMessageSourceAccessor().getMessage("probe.src.log.reload"), name,
174 contextName);
175 }
176 }
177 } else {
178 errMsg = getMessageSourceAccessor().getMessage("probe.src.deploy.file.pathNotValid");
179 }
180 } else {
181 errMsg = getMessageSourceAccessor().getMessage("probe.src.deploy.file.notPath");
182 }
183 } else {
184 errMsg = getMessageSourceAccessor().getMessage("probe.src.deploy.file.notExists",
185 new Object[] {visibleContextName});
186 }
187 } catch (IOException e) {
188 errMsg = getMessageSourceAccessor().getMessage("probe.src.deploy.file.failure",
189 new Object[] {e.getMessage()});
190 logger.error("Tomcat threw an exception when trying to deploy", e);
191 } finally {
192 if (errMsg != null) {
193 request.setAttribute("errorMessage", errMsg);
194 }
195
196 Files.delete(tmpPath);
197 }
198 return new ModelAndView(new InternalResourceView(getViewName()));
199 }
200
201 @Value("/adm/deploy.htm")
202 @Override
203 public void setViewName(String viewName) {
204 super.setViewName(viewName);
205 }
206
207 }