feat: show creating time in file upload overview
Closes: gh-1551
This commit is contained in:
		| @ -22,14 +22,18 @@ | ||||
|  | ||||
| package org.owasp.webgoat.webwolf; | ||||
|  | ||||
| import static java.util.Comparator.comparing; | ||||
| import static org.springframework.http.MediaType.ALL_VALUE; | ||||
|  | ||||
| import jakarta.servlet.http.HttpServletRequest; | ||||
| import java.io.File; | ||||
| 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 lombok.AllArgsConstructor; | ||||
| import lombok.Getter; | ||||
| import java.util.TimeZone; | ||||
| import lombok.extern.slf4j.Slf4j; | ||||
| import org.apache.commons.io.FileUtils; | ||||
| import org.springframework.beans.factory.annotation.Value; | ||||
| @ -51,6 +55,9 @@ import org.springframework.web.servlet.view.RedirectView; | ||||
| @Slf4j | ||||
| public class FileServer { | ||||
|  | ||||
|   private static final DateTimeFormatter dateTimeFormatter = | ||||
|       DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); | ||||
|  | ||||
|   @Value("${webwolf.fileserver.location}") | ||||
|   private String fileLocation; | ||||
|  | ||||
| @ -87,16 +94,9 @@ public class FileServer { | ||||
|         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") | ||||
|   public ModelAndView getFiles(HttpServletRequest request, Authentication authentication) { | ||||
|   public ModelAndView getFiles( | ||||
|       HttpServletRequest request, Authentication authentication, TimeZone timezone) { | ||||
|     String username = (null != authentication) ? authentication.getName() : "anonymous"; | ||||
|     File destinationDir = new File(fileLocation, username); | ||||
|  | ||||
| @ -108,18 +108,33 @@ public class FileServer { | ||||
|     } | ||||
|     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); | ||||
|     if (files != null) { | ||||
|       for (File file : files) { | ||||
|         String size = FileUtils.byteCountToDisplaySize(file.length()); | ||||
|         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); | ||||
|     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"; | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -1,8 +1,8 @@ | ||||
| server.error.include-stacktrace=always | ||||
| server.error.path=/error.html | ||||
| server.servlet.context-path=${webwolf.context} | ||||
| server.port=${WEBWOLF_PORT:9090} | ||||
| server.address=0.0.0.0 | ||||
| server.port=${webwolf.port} | ||||
| server.address=${webwolf.host} | ||||
| spring.application.name=WebWolf | ||||
|  | ||||
| webwolf.host=${WEBWOLF_HOST:127.0.0.1} | ||||
|  | ||||
| @ -51,16 +51,15 @@ | ||||
|         <tr> | ||||
|             <th>Filename</th> | ||||
|             <th>Size</th> | ||||
|             <th>Link</th> | ||||
|             <th>Creation time</th> | ||||
|         </tr> | ||||
|         </thead> | ||||
|         <tbody> | ||||
|         <tr th:each="f : ${files}"> | ||||
|             <td th:text="${f.name}">filename</td> | ||||
|             <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><a th:id="fileLink" th:href="@{'/' + ${f.link}}" th:text="${f.name}">link</a> | ||||
|             </td> | ||||
|             <td th:text="${f.size}">size</td> | ||||
|             <td th:text="${f.creationTime}">creation time</td> | ||||
|         </tr> | ||||
|         </tbody> | ||||
|     </table> | ||||
|  | ||||
		Reference in New Issue
	
	Block a user