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 = getContainerWrapper().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 = getContainerWrapper().getTomcatContainer().formatContextName(contextName);
129
130
131
132
133
134 String visibleContextName = contextName.isEmpty() ? "/" : contextName;
135 request.setAttribute("contextName", visibleContextName);
136
137
138 if (getContainerWrapper().getTomcatContainer().findContext(contextName) != null) {
139
140 File destFile = Path.of(getContainerWrapper().getTomcatContainer().getAppBase().getPath(),
141 contextName + where).toFile();
142
143
144 if (destFile.exists()) {
145 if (!destFile.getAbsolutePath().contains("..")) {
146
147 FileUtils.copyFileToDirectory(tmpPath.toFile(), destFile);
148
149 request.setAttribute("successFile", Boolean.TRUE);
150
151 Authentication auth = SecurityContextHolder.getContext().getAuthentication();
152
153 String name = auth.getName();
154 if (contextName.matches("\\w*")) {
155 logger.info(getMessageSourceAccessor().getMessage("probe.src.log.copyfile"), name,
156 contextName);
157 }
158 Context context = getContainerWrapper().getTomcatContainer().findContext(contextName);
159
160 if ("yes".equalsIgnoreCase(discardParam)) {
161 getContainerWrapper().getTomcatContainer().discardWorkDir(context);
162 if (contextName.matches("\\w*")) {
163 logger.info(getMessageSourceAccessor().getMessage("probe.src.log.discardwork"),
164 name, contextName);
165 }
166 }
167
168 if ("yes".equalsIgnoreCase(reloadParam) && context != null) {
169 context.reload();
170 request.setAttribute("reloadContext", Boolean.TRUE);
171 if (contextName.matches("\\w*")) {
172 logger.info(getMessageSourceAccessor().getMessage("probe.src.log.reload"), name,
173 contextName);
174 }
175 }
176 } else {
177 errMsg = getMessageSourceAccessor().getMessage("probe.src.deploy.file.pathNotValid");
178 }
179 } else {
180 errMsg = getMessageSourceAccessor().getMessage("probe.src.deploy.file.notPath");
181 }
182 } else {
183 errMsg = getMessageSourceAccessor().getMessage("probe.src.deploy.file.notExists",
184 new Object[] {visibleContextName});
185 }
186 } catch (IOException e) {
187 errMsg = getMessageSourceAccessor().getMessage("probe.src.deploy.file.failure",
188 new Object[] {e.getMessage()});
189 logger.error("Tomcat threw an exception when trying to deploy", e);
190 } finally {
191 if (errMsg != null) {
192 request.setAttribute("errorMessage", errMsg);
193 }
194
195 Files.delete(tmpPath);
196 }
197 return new ModelAndView(new InternalResourceView(getViewName()));
198 }
199
200 @Value("/adm/deploy.htm")
201 @Override
202 public void setViewName(String viewName) {
203 super.setViewName(viewName);
204 }
205
206 }