From a3f3108e87e9587bfbfe7ee1a150a73c80396236 Mon Sep 17 00:00:00 2001 From: RhiobeT Date: Wed, 1 Dec 2021 19:22:46 +0100 Subject: [PATCH] Add advent feature --- .../rhiobet/lalafin/api/FilePrivateAPI.java | 7 ++- .../api/advent/AdventAccessService.java | 60 +++++++++++++++++++ .../api/advent/AdventConfiguration.java | 17 ++++++ .../rhiobet/lalafin/file/FileInfoService.java | 28 ++++++++- .../sh/rhiobet/lalafin/file/FileResource.java | 7 ++- .../rhiobet/lalafin/file/ViewerResource.java | 7 ++- src/main/resources/application.yaml.example | 8 ++- 7 files changed, 129 insertions(+), 5 deletions(-) create mode 100644 src/main/java/sh/rhiobet/lalafin/api/advent/AdventAccessService.java create mode 100644 src/main/java/sh/rhiobet/lalafin/api/advent/AdventConfiguration.java diff --git a/src/main/java/sh/rhiobet/lalafin/api/FilePrivateAPI.java b/src/main/java/sh/rhiobet/lalafin/api/FilePrivateAPI.java index a36926f..f4b4ed8 100644 --- a/src/main/java/sh/rhiobet/lalafin/api/FilePrivateAPI.java +++ b/src/main/java/sh/rhiobet/lalafin/api/FilePrivateAPI.java @@ -14,6 +14,7 @@ import org.jboss.resteasy.annotations.jaxrs.PathParam; import io.quarkus.security.Authenticated; import io.quarkus.security.identity.SecurityIdentity; import io.vertx.core.http.HttpServerRequest; +import sh.rhiobet.lalafin.api.advent.AdventAccessService; import sh.rhiobet.lalafin.api.internal.FileTokenProvider; import sh.rhiobet.lalafin.api.internal.RoleAccessService; import sh.rhiobet.lalafin.api.model.FileInfoBase; @@ -34,6 +35,9 @@ public class FilePrivateAPI { @Inject RoleAccessService roleAccessService; + @Inject + AdventAccessService adventAccessService; + @GET @Path("/") @Produces(MediaType.APPLICATION_JSON) @@ -45,7 +49,8 @@ public class FilePrivateAPI { @Path("/{names: .+}") @Produces(MediaType.APPLICATION_JSON) public Response getFileInfo(@PathParam List names) { - if (!roleAccessService.checkRouteAccess(securityIdentity.getRoles(), names)) { + if (!roleAccessService.checkRouteAccess(securityIdentity.getRoles(), names) + || !adventAccessService.checkEventAccess(names)) { return Response.status(Response.Status.FORBIDDEN).build(); } diff --git a/src/main/java/sh/rhiobet/lalafin/api/advent/AdventAccessService.java b/src/main/java/sh/rhiobet/lalafin/api/advent/AdventAccessService.java new file mode 100644 index 0000000..c3e63a9 --- /dev/null +++ b/src/main/java/sh/rhiobet/lalafin/api/advent/AdventAccessService.java @@ -0,0 +1,60 @@ +package sh.rhiobet.lalafin.api.advent; + +import java.time.LocalDateTime; +import java.util.List; +import javax.enterprise.context.ApplicationScoped; +import javax.inject.Inject; +import javax.ws.rs.core.PathSegment; +import sh.rhiobet.lalafin.api.advent.AdventConfiguration.AdventEvent; + +@ApplicationScoped +public class AdventAccessService { + + @Inject + AdventConfiguration adventConfiguration; + + public boolean checkEventAccess(final String requestedUri) { + return this.checkEventAccess(requestedUri.replaceFirst("^/", "").split("/")); + } + + public boolean checkEventAccess(final List names) { + return this.checkEventAccess(names.stream().map(n -> n.getPath()).toArray(String[]::new)); + } + + public boolean checkEventAccess(final String[] names) { + for (AdventEvent event : adventConfiguration.events()) { + String[] splittedPath = event.path().replaceFirst("^/", "").split("/"); + // split returns a non empty array if the path is "/" + if (splittedPath.length == 1 && splittedPath[0].isEmpty()) { + continue; + } + + int i; + boolean match = true; + for (i = 0; i < splittedPath.length; i++) { + if (i >= names.length || !splittedPath[i].equals(names[i])) { + match = false; + break; + } + } + if (match && names.length > i) { + String dayString = names[i].replaceAll("\\..*$", ""); + try { + int day = Integer.parseInt(dayString); + LocalDateTime now = LocalDateTime.now(); + if (now.getYear() >= event.year() && now.getMonthValue() >= event.month() + && now.getDayOfMonth() >= day) { + return true; + } else { + return false; + } + } catch (NumberFormatException ignored) { + + } + } + } + + return true; + } + +} diff --git a/src/main/java/sh/rhiobet/lalafin/api/advent/AdventConfiguration.java b/src/main/java/sh/rhiobet/lalafin/api/advent/AdventConfiguration.java new file mode 100644 index 0000000..a31bc65 --- /dev/null +++ b/src/main/java/sh/rhiobet/lalafin/api/advent/AdventConfiguration.java @@ -0,0 +1,17 @@ +package sh.rhiobet.lalafin.api.advent; + +import java.util.List; +import io.smallrye.config.ConfigMapping; + +@ConfigMapping(prefix = "api.advent") +public interface AdventConfiguration { + + public List events(); + + public static interface AdventEvent { + public String path(); + public int year(); + public int month(); + } + +} \ No newline at end of file diff --git a/src/main/java/sh/rhiobet/lalafin/file/FileInfoService.java b/src/main/java/sh/rhiobet/lalafin/file/FileInfoService.java index f3da2ea..bf5ad0b 100644 --- a/src/main/java/sh/rhiobet/lalafin/file/FileInfoService.java +++ b/src/main/java/sh/rhiobet/lalafin/file/FileInfoService.java @@ -11,6 +11,7 @@ import java.util.List; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import javax.ws.rs.core.PathSegment; +import sh.rhiobet.lalafin.api.advent.AdventAccessService; import sh.rhiobet.lalafin.api.configuration.FileApiConfiguration; import sh.rhiobet.lalafin.api.internal.FileTokenProvider; import sh.rhiobet.lalafin.api.model.FileInfo; @@ -25,6 +26,9 @@ public class FileInfoService { @Inject ThumbnailService thumbnailService; + @Inject + AdventAccessService adventAccessService; + public FileInfoBase getInfo(List names, FileTokenProvider fileTokenProvider) { String requestedPath = ""; String requestedFilename = ""; @@ -110,7 +114,7 @@ public class FileInfoService { + fileName + ".jpg"); if (!Files.exists(thumbPath)) { thumbPath = Paths.get("/lalafin/file" + requestedPath - + "/.thumbnails/" + fileName + ".png"); + + "/.thumbnails/" + fileName + ".png"); } } catch (Exception ignored) { } @@ -145,6 +149,28 @@ public class FileInfoService { contentInfo.thumbnailUrl += ".png"; } } + if (!adventAccessService.checkEventAccess(requestedUri + "/" + fileUri)) { + ((FileInfo) contentInfo).publicApiUrl = "/api/private/file/403"; + try { + thumbPath = Paths.get( + "/lalafin/file" + requestedPath + "/.thumbnails/00.jpg"); + if (!Files.exists(thumbPath)) { + thumbPath = Paths.get("/lalafin/file" + requestedPath + + "/.thumbnails/00.png"); + } + if (Files.exists(thumbPath)) { + contentInfo.thumbnailUrl = + "/file" + requestedUri + "/.thumbnails/00"; + if (thumbPath.toString().endsWith(".jpg")) { + contentInfo.thumbnailUrl += ".jpg"; + } else if (thumbPath.toString().endsWith(".png")) { + contentInfo.thumbnailUrl += ".png"; + } + } + } catch (Exception ignored) { + + } + } folderInfo.content.add(contentInfo); }); } catch (IOException ignored) { diff --git a/src/main/java/sh/rhiobet/lalafin/file/FileResource.java b/src/main/java/sh/rhiobet/lalafin/file/FileResource.java index 30dc324..dca7117 100644 --- a/src/main/java/sh/rhiobet/lalafin/file/FileResource.java +++ b/src/main/java/sh/rhiobet/lalafin/file/FileResource.java @@ -16,6 +16,7 @@ import org.jboss.resteasy.annotations.jaxrs.PathParam; import io.quarkus.security.Authenticated; import io.quarkus.security.identity.SecurityIdentity; import io.vertx.core.http.HttpServerRequest; +import sh.rhiobet.lalafin.api.advent.AdventAccessService; import sh.rhiobet.lalafin.api.internal.FileTokenProvider; import sh.rhiobet.lalafin.api.internal.RoleAccessService; import sh.rhiobet.lalafin.api.model.FileInfo; @@ -43,6 +44,9 @@ public class FileResource { @Inject RoleAccessService roleAccessService; + @Inject + AdventAccessService adventAccessService; + @GET @Path("/") public Response serveRoot(@HeaderParam("Range") String range) { @@ -52,7 +56,8 @@ public class FileResource { @GET @Path("/{names: .+}") public Response serve(@PathParam List names, @HeaderParam("Range") String range) { - if (!roleAccessService.checkRouteAccess(securityIdentity.getRoles(), names)) { + if (!roleAccessService.checkRouteAccess(securityIdentity.getRoles(), names) + || !adventAccessService.checkEventAccess(names)) { return Response.status(Response.Status.FORBIDDEN).build(); } diff --git a/src/main/java/sh/rhiobet/lalafin/file/ViewerResource.java b/src/main/java/sh/rhiobet/lalafin/file/ViewerResource.java index 3193f4a..8e3c61e 100644 --- a/src/main/java/sh/rhiobet/lalafin/file/ViewerResource.java +++ b/src/main/java/sh/rhiobet/lalafin/file/ViewerResource.java @@ -13,6 +13,7 @@ import org.jboss.resteasy.annotations.jaxrs.PathParam; import io.quarkus.security.Authenticated; import io.quarkus.security.identity.SecurityIdentity; import io.vertx.core.http.HttpServerRequest; +import sh.rhiobet.lalafin.api.advent.AdventAccessService; import sh.rhiobet.lalafin.api.internal.FileTokenProvider; import sh.rhiobet.lalafin.api.internal.RoleAccessService; import sh.rhiobet.lalafin.api.model.FileInfoBase; @@ -26,6 +27,9 @@ public class ViewerResource { @Inject RoleAccessService roleAccessService; + @Inject + AdventAccessService adventAccessService; + @Inject FileInfoService fileInfoService; @@ -38,7 +42,8 @@ public class ViewerResource { @GET @Path("/{names: .+}/{page}") public Response view(@PathParam List names, @PathParam int page) { - if (!roleAccessService.checkRouteAccess(securityIdentity.getRoles(), names)) { + if (!roleAccessService.checkRouteAccess(securityIdentity.getRoles(), names) + || !adventAccessService.checkEventAccess(names)) { return Response.status(Response.Status.FORBIDDEN).build(); } diff --git a/src/main/resources/application.yaml.example b/src/main/resources/application.yaml.example index 422e07f..d41aede 100644 --- a/src/main/resources/application.yaml.example +++ b/src/main/resources/application.yaml.example @@ -36,4 +36,10 @@ api: # thumbnail: # jellyfin: - # paths: {} \ No newline at end of file + # paths: {} + + # advent: + # events: + # - path: / + # year: 2021 + # month: 12 \ No newline at end of file