feat: show creating time in file upload overview

Closes: gh-1551
This commit is contained in:
Nanne Baars 2023-12-04 10:17:34 +01:00
parent c7c2a61f65
commit 3d651526be
3 changed files with 35 additions and 21 deletions

View File

@ -22,14 +22,18 @@
package org.owasp.webgoat.webwolf; package org.owasp.webgoat.webwolf;
import static java.util.Comparator.comparing;
import static org.springframework.http.MediaType.ALL_VALUE; import static org.springframework.http.MediaType.ALL_VALUE;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.attribute.FileTime;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList; import java.util.ArrayList;
import lombok.AllArgsConstructor; import java.util.TimeZone;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
@ -51,6 +55,9 @@ import org.springframework.web.servlet.view.RedirectView;
@Slf4j @Slf4j
public class FileServer { public class FileServer {
private static final DateTimeFormatter dateTimeFormatter =
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
@Value("${webwolf.fileserver.location}") @Value("${webwolf.fileserver.location}")
private String fileLocation; private String fileLocation;
@ -87,16 +94,9 @@ public class FileServer {
new ModelMap().addAttribute("uploadSuccess", "File uploaded successful")); new ModelMap().addAttribute("uploadSuccess", "File uploaded successful"));
} }
@AllArgsConstructor
@Getter
private class UploadedFile {
private final String name;
private final String size;
private final String link;
}
@GetMapping(value = "/files") @GetMapping(value = "/files")
public ModelAndView getFiles(HttpServletRequest request, Authentication authentication) { public ModelAndView getFiles(
HttpServletRequest request, Authentication authentication, TimeZone timezone) {
String username = (null != authentication) ? authentication.getName() : "anonymous"; String username = (null != authentication) ? authentication.getName() : "anonymous";
File destinationDir = new File(fileLocation, username); File destinationDir = new File(fileLocation, username);
@ -108,18 +108,33 @@ public class FileServer {
} }
changeIndicatorFile.delete(); changeIndicatorFile.delete();
var uploadedFiles = new ArrayList<>(); record UploadedFile(String name, String size, String link, String creationTime) {}
var uploadedFiles = new ArrayList<UploadedFile>();
File[] files = destinationDir.listFiles(File::isFile); File[] files = destinationDir.listFiles(File::isFile);
if (files != null) { if (files != null) {
for (File file : files) { for (File file : files) {
String size = FileUtils.byteCountToDisplaySize(file.length()); String size = FileUtils.byteCountToDisplaySize(file.length());
String link = String.format("files/%s/%s", username, file.getName()); String link = String.format("files/%s/%s", username, file.getName());
uploadedFiles.add(new UploadedFile(file.getName(), size, link)); uploadedFiles.add(
new UploadedFile(file.getName(), size, link, getCreationTime(timezone, file)));
} }
} }
modelAndView.addObject("files", uploadedFiles); modelAndView.addObject(
"files",
uploadedFiles.stream().sorted(comparing(UploadedFile::creationTime).reversed()).toList());
modelAndView.addObject("webwolf_url", "http://" + server + ":" + port + contextPath); modelAndView.addObject("webwolf_url", "http://" + server + ":" + port + contextPath);
return modelAndView; return modelAndView;
} }
private String getCreationTime(TimeZone timezone, File file) {
try {
FileTime creationTime = (FileTime) Files.getAttribute(file.toPath(), "creationTime");
ZonedDateTime zonedDateTime = creationTime.toInstant().atZone(timezone.toZoneId());
return dateTimeFormatter.format(zonedDateTime);
} catch (IOException e) {
return "unknown";
}
}
} }

View File

@ -1,8 +1,8 @@
server.error.include-stacktrace=always server.error.include-stacktrace=always
server.error.path=/error.html server.error.path=/error.html
server.servlet.context-path=${webwolf.context} server.servlet.context-path=${webwolf.context}
server.port=${WEBWOLF_PORT:9090} server.port=${webwolf.port}
server.address=0.0.0.0 server.address=${webwolf.host}
spring.application.name=WebWolf spring.application.name=WebWolf
webwolf.host=${WEBWOLF_HOST:127.0.0.1} webwolf.host=${WEBWOLF_HOST:127.0.0.1}

View File

@ -51,16 +51,15 @@
<tr> <tr>
<th>Filename</th> <th>Filename</th>
<th>Size</th> <th>Size</th>
<th>Link</th> <th>Creation time</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr th:each="f : ${files}"> <tr th:each="f : ${files}">
<td th:text="${f.name}">filename</td> <td><a th:id="fileLink" th:href="@{'/' + ${f.link}}" th:text="${f.name}">link</a>
<td th:text="${f.size}">size</td>
<td><a th:id="fileLink" th:href="@{'/' + ${f.link}}">link</a>
<span class="fa fa-files-o" title="Click to copy to clipboard"></span>
</td> </td>
<td th:text="${f.size}">size</td>
<td th:text="${f.creationTime}">creation time</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>