1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.codelibs.fess.app.web.admin.log;
17
18 import java.io.IOException;
19 import java.io.InputStream;
20 import java.nio.charset.StandardCharsets;
21 import java.nio.file.Files;
22 import java.nio.file.Path;
23 import java.nio.file.Paths;
24 import java.util.ArrayList;
25 import java.util.Base64;
26 import java.util.Date;
27 import java.util.HashMap;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.stream.Stream;
31
32 import org.codelibs.core.lang.StringUtil;
33 import org.codelibs.fess.annotation.Secured;
34 import org.codelibs.fess.app.web.base.FessAdminAction;
35 import org.codelibs.fess.exception.FessSystemException;
36 import org.codelibs.fess.helper.SystemHelper;
37 import org.codelibs.fess.util.ComponentUtil;
38 import org.codelibs.fess.util.RenderDataUtil;
39 import org.lastaflute.di.exception.IORuntimeException;
40 import org.lastaflute.web.Execute;
41 import org.lastaflute.web.response.ActionResponse;
42 import org.lastaflute.web.response.HtmlResponse;
43 import org.lastaflute.web.ruts.process.ActionRuntime;
44
45
46
47
48 public class AdminLogAction extends FessAdminAction {
49
50
51
52
53 public AdminLogAction() {
54 super();
55 }
56
57
58 public static final String ROLE = "admin-log";
59
60 @Override
61 protected void setupHtmlData(final ActionRuntime runtime) {
62 super.setupHtmlData(runtime);
63 runtime.registerData("helpLink", systemHelper.getHelpLink(fessConfig.getOnlineHelpNameLog()));
64 }
65
66 @Override
67 protected String getActionRole() {
68 return ROLE;
69 }
70
71
72
73
74
75
76 @Execute
77 @Secured({ ROLE, ROLE + VIEW })
78 public HtmlResponse index() {
79 return asIndexHtml();
80 }
81
82
83
84
85
86
87
88 @Execute
89 @Secured({ ROLE, ROLE + VIEW })
90 public ActionResponse download(final String id) {
91 final String filename = sanitizeFilename(new String(Base64.getDecoder().decode(id), StandardCharsets.UTF_8));
92 final String logFilePath = systemHelper.getLogFilePath();
93 if (StringUtil.isNotBlank(logFilePath) && isLogFilename(filename)) {
94 final Path path = Paths.get(logFilePath, filename);
95 return asStream(filename).contentTypeOctetStream().stream(out -> {
96 try (InputStream in = Files.newInputStream(path)) {
97 out.write(in);
98 }
99 });
100 }
101 throwValidationError(messages -> messages.addErrorsCouldNotFindLogFile(GLOBAL, filename), this::asIndexHtml);
102 return redirect(getClass());
103 }
104
105
106
107
108
109
110
111 public static String sanitizeFilename(final String filename) {
112 return filename.replaceAll("\\s", "").replace("\\", "/").replace("..", "").replaceAll("/+", "/");
113 }
114
115
116
117
118
119
120 public static List<Map<String, Object>> getLogFileItems() {
121 final SystemHelper systemHelper = ComponentUtil.getSystemHelper();
122 final List<Map<String, Object>> logFileItems = new ArrayList<>();
123 final String logFilePath = systemHelper.getLogFilePath();
124 if (StringUtil.isNotBlank(logFilePath)) {
125 final Path logDirPath = Paths.get(logFilePath);
126 try (Stream<Path> stream = Files.list(logDirPath)) {
127 stream.filter(entry -> isLogFilename(entry.getFileName().toString())).sorted().forEach(filePath -> {
128 final Map<String, Object> map = new HashMap<>();
129 final String name = filePath.getFileName().toString();
130 map.put("id", Base64.getUrlEncoder().encodeToString(name.getBytes(StandardCharsets.UTF_8)));
131 map.put("name", name);
132 try {
133 map.put("lastModified", new Date(Files.getLastModifiedTime(filePath).toMillis()));
134 } catch (final IOException e) {
135 throw new IORuntimeException(e);
136 }
137 logFileItems.add(map);
138 });
139 } catch (final Exception e) {
140 throw new FessSystemException("Failed to access log files: logFilePath=" + logFilePath, e);
141 }
142 }
143 return logFileItems;
144 }
145
146
147
148
149
150
151
152 public static boolean isLogFilename(final String name) {
153 return name.endsWith(".log") || name.endsWith(".log.gz");
154 }
155
156 private HtmlResponse asIndexHtml() {
157 return asHtml(path_AdminLog_AdminLogJsp).renderWith(data -> {
158 RenderDataUtil.register(data, "logFileItems", getLogFileItems());
159 });
160 }
161
162 }