Add advent feature
This commit is contained in:
@@ -14,6 +14,7 @@ import org.jboss.resteasy.annotations.jaxrs.PathParam;
|
|||||||
import io.quarkus.security.Authenticated;
|
import io.quarkus.security.Authenticated;
|
||||||
import io.quarkus.security.identity.SecurityIdentity;
|
import io.quarkus.security.identity.SecurityIdentity;
|
||||||
import io.vertx.core.http.HttpServerRequest;
|
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.FileTokenProvider;
|
||||||
import sh.rhiobet.lalafin.api.internal.RoleAccessService;
|
import sh.rhiobet.lalafin.api.internal.RoleAccessService;
|
||||||
import sh.rhiobet.lalafin.api.model.FileInfoBase;
|
import sh.rhiobet.lalafin.api.model.FileInfoBase;
|
||||||
@@ -34,6 +35,9 @@ public class FilePrivateAPI {
|
|||||||
@Inject
|
@Inject
|
||||||
RoleAccessService roleAccessService;
|
RoleAccessService roleAccessService;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
AdventAccessService adventAccessService;
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Path("/")
|
@Path("/")
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
@@ -45,7 +49,8 @@ public class FilePrivateAPI {
|
|||||||
@Path("/{names: .+}")
|
@Path("/{names: .+}")
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
public Response getFileInfo(@PathParam List<PathSegment> names) {
|
public Response getFileInfo(@PathParam List<PathSegment> names) {
|
||||||
if (!roleAccessService.checkRouteAccess(securityIdentity.getRoles(), names)) {
|
if (!roleAccessService.checkRouteAccess(securityIdentity.getRoles(), names)
|
||||||
|
|| !adventAccessService.checkEventAccess(names)) {
|
||||||
return Response.status(Response.Status.FORBIDDEN).build();
|
return Response.status(Response.Status.FORBIDDEN).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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<PathSegment> 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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<AdventEvent> events();
|
||||||
|
|
||||||
|
public static interface AdventEvent {
|
||||||
|
public String path();
|
||||||
|
public int year();
|
||||||
|
public int month();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -11,6 +11,7 @@ import java.util.List;
|
|||||||
import javax.enterprise.context.ApplicationScoped;
|
import javax.enterprise.context.ApplicationScoped;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.ws.rs.core.PathSegment;
|
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.configuration.FileApiConfiguration;
|
||||||
import sh.rhiobet.lalafin.api.internal.FileTokenProvider;
|
import sh.rhiobet.lalafin.api.internal.FileTokenProvider;
|
||||||
import sh.rhiobet.lalafin.api.model.FileInfo;
|
import sh.rhiobet.lalafin.api.model.FileInfo;
|
||||||
@@ -25,6 +26,9 @@ public class FileInfoService {
|
|||||||
@Inject
|
@Inject
|
||||||
ThumbnailService thumbnailService;
|
ThumbnailService thumbnailService;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
AdventAccessService adventAccessService;
|
||||||
|
|
||||||
public FileInfoBase getInfo(List<PathSegment> names, FileTokenProvider fileTokenProvider) {
|
public FileInfoBase getInfo(List<PathSegment> names, FileTokenProvider fileTokenProvider) {
|
||||||
String requestedPath = "";
|
String requestedPath = "";
|
||||||
String requestedFilename = "";
|
String requestedFilename = "";
|
||||||
@@ -110,7 +114,7 @@ public class FileInfoService {
|
|||||||
+ fileName + ".jpg");
|
+ fileName + ".jpg");
|
||||||
if (!Files.exists(thumbPath)) {
|
if (!Files.exists(thumbPath)) {
|
||||||
thumbPath = Paths.get("/lalafin/file" + requestedPath
|
thumbPath = Paths.get("/lalafin/file" + requestedPath
|
||||||
+ "/.thumbnails/" + fileName + ".png");
|
+ "/.thumbnails/" + fileName + ".png");
|
||||||
}
|
}
|
||||||
} catch (Exception ignored) {
|
} catch (Exception ignored) {
|
||||||
}
|
}
|
||||||
@@ -145,6 +149,28 @@ public class FileInfoService {
|
|||||||
contentInfo.thumbnailUrl += ".png";
|
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);
|
folderInfo.content.add(contentInfo);
|
||||||
});
|
});
|
||||||
} catch (IOException ignored) {
|
} catch (IOException ignored) {
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import org.jboss.resteasy.annotations.jaxrs.PathParam;
|
|||||||
import io.quarkus.security.Authenticated;
|
import io.quarkus.security.Authenticated;
|
||||||
import io.quarkus.security.identity.SecurityIdentity;
|
import io.quarkus.security.identity.SecurityIdentity;
|
||||||
import io.vertx.core.http.HttpServerRequest;
|
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.FileTokenProvider;
|
||||||
import sh.rhiobet.lalafin.api.internal.RoleAccessService;
|
import sh.rhiobet.lalafin.api.internal.RoleAccessService;
|
||||||
import sh.rhiobet.lalafin.api.model.FileInfo;
|
import sh.rhiobet.lalafin.api.model.FileInfo;
|
||||||
@@ -43,6 +44,9 @@ public class FileResource {
|
|||||||
@Inject
|
@Inject
|
||||||
RoleAccessService roleAccessService;
|
RoleAccessService roleAccessService;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
AdventAccessService adventAccessService;
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Path("/")
|
@Path("/")
|
||||||
public Response serveRoot(@HeaderParam("Range") String range) {
|
public Response serveRoot(@HeaderParam("Range") String range) {
|
||||||
@@ -52,7 +56,8 @@ public class FileResource {
|
|||||||
@GET
|
@GET
|
||||||
@Path("/{names: .+}")
|
@Path("/{names: .+}")
|
||||||
public Response serve(@PathParam List<PathSegment> names, @HeaderParam("Range") String range) {
|
public Response serve(@PathParam List<PathSegment> 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();
|
return Response.status(Response.Status.FORBIDDEN).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import org.jboss.resteasy.annotations.jaxrs.PathParam;
|
|||||||
import io.quarkus.security.Authenticated;
|
import io.quarkus.security.Authenticated;
|
||||||
import io.quarkus.security.identity.SecurityIdentity;
|
import io.quarkus.security.identity.SecurityIdentity;
|
||||||
import io.vertx.core.http.HttpServerRequest;
|
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.FileTokenProvider;
|
||||||
import sh.rhiobet.lalafin.api.internal.RoleAccessService;
|
import sh.rhiobet.lalafin.api.internal.RoleAccessService;
|
||||||
import sh.rhiobet.lalafin.api.model.FileInfoBase;
|
import sh.rhiobet.lalafin.api.model.FileInfoBase;
|
||||||
@@ -26,6 +27,9 @@ public class ViewerResource {
|
|||||||
@Inject
|
@Inject
|
||||||
RoleAccessService roleAccessService;
|
RoleAccessService roleAccessService;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
AdventAccessService adventAccessService;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
FileInfoService fileInfoService;
|
FileInfoService fileInfoService;
|
||||||
|
|
||||||
@@ -38,7 +42,8 @@ public class ViewerResource {
|
|||||||
@GET
|
@GET
|
||||||
@Path("/{names: .+}/{page}")
|
@Path("/{names: .+}/{page}")
|
||||||
public Response view(@PathParam List<PathSegment> names, @PathParam int page) {
|
public Response view(@PathParam List<PathSegment> 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();
|
return Response.status(Response.Status.FORBIDDEN).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,3 +37,9 @@ api:
|
|||||||
# thumbnail:
|
# thumbnail:
|
||||||
# jellyfin:
|
# jellyfin:
|
||||||
# paths: {}
|
# paths: {}
|
||||||
|
|
||||||
|
# advent:
|
||||||
|
# events:
|
||||||
|
# - path: /
|
||||||
|
# year: 2021
|
||||||
|
# month: 12
|
||||||
Reference in New Issue
Block a user