diff --git a/src/main/java/sh/rhiobet/lalafin/file/access/FileToken.java b/src/main/java/sh/rhiobet/lalafin/file/access/FileToken.java new file mode 100644 index 0000000..25abea6 --- /dev/null +++ b/src/main/java/sh/rhiobet/lalafin/file/access/FileToken.java @@ -0,0 +1,20 @@ +package sh.rhiobet.lalafin.file.access; + +import io.quarkus.runtime.annotations.RegisterForReflection; + +@RegisterForReflection +public class FileToken { + public String user; + public long timestamp; + public String ip; + public String file; + + public FileToken() {} + + public FileToken(String user, long timestamp, String ip, String file) { + this.user = user; + this.timestamp = timestamp; + this.ip = ip; + this.file = file; + } +} diff --git a/src/main/java/sh/rhiobet/lalafin/file/access/FileTokenProvider.java b/src/main/java/sh/rhiobet/lalafin/file/access/FileTokenProvider.java new file mode 100644 index 0000000..1d7d316 --- /dev/null +++ b/src/main/java/sh/rhiobet/lalafin/file/access/FileTokenProvider.java @@ -0,0 +1,34 @@ +package sh.rhiobet.lalafin.file.access; + +import java.util.UUID; + +import io.quarkus.redis.datasource.RedisDataSource; +import io.quarkus.redis.datasource.value.SetArgs; +import io.quarkus.security.identity.SecurityIdentity; +import io.vertx.core.http.HttpServerRequest; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; + +@ApplicationScoped +public class FileTokenProvider { + @Inject + RedisDataSource redisDataSource; + + @Inject + SecurityIdentity securityIdentity; + + @Inject + HttpServerRequest request; + + public String getFileToken(String fileUri) { + FileToken token = new FileToken(this.securityIdentity.getPrincipal().getName(), + System.currentTimeMillis(), this.request.remoteAddress().host(), fileUri); + + String uniqueID = UUID.randomUUID().toString(); + + this.redisDataSource.value(FileToken.class).set( + "fileToken-" + uniqueID, token, new SetArgs().pxAt(System.currentTimeMillis() + 86400000)); + + return uniqueID; + } +} diff --git a/src/main/java/sh/rhiobet/lalafin/file/model/FileInfo.java b/src/main/java/sh/rhiobet/lalafin/file/model/FileInfo.java index 4a5a279..1ceb66b 100644 --- a/src/main/java/sh/rhiobet/lalafin/file/model/FileInfo.java +++ b/src/main/java/sh/rhiobet/lalafin/file/model/FileInfo.java @@ -11,7 +11,7 @@ public class FileInfo extends FileInfoBase { this.publicApiUrl = publicApiUrl; } - public FileInfo(String filename, String directUrl) { - this(filename, "", directUrl, ""); + public FileInfo(String filename, String directUrl, String publicApiUrl) { + this(filename, "", directUrl, publicApiUrl); } } diff --git a/src/main/java/sh/rhiobet/lalafin/file/model/FileMetadataService.java b/src/main/java/sh/rhiobet/lalafin/file/model/FileMetadataService.java index ee91ea6..44d419d 100644 --- a/src/main/java/sh/rhiobet/lalafin/file/model/FileMetadataService.java +++ b/src/main/java/sh/rhiobet/lalafin/file/model/FileMetadataService.java @@ -7,7 +7,6 @@ import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.inject.Named; import sh.rhiobet.lalafin.LalafinConfiguration; -import sh.rhiobet.lalafin.api.internal.redis.FileTokenProvider; import sh.rhiobet.lalafin.core.path.model.Path; import sh.rhiobet.lalafin.core.path.resolver.PathURIResolver; import sh.rhiobet.lalafin.core.thumbnail.ThumbnailGenerator; @@ -29,11 +28,15 @@ public class FileMetadataService { @Named("file/resolver/thumbnail") PathURIResolver fileThumbnailURIResolver; + @Inject + @Named("file/resolver/token") + PathURIResolver fileTokenURIResolver; + @Inject @Named("file/thumbnail") ThumbnailGenerator fileThumbnailGenerator; - public FileInfoBase getInfo(Path filePath, FileTokenProvider fileTokenProvider) { + public FileInfoBase getInfo(Path filePath) { if (filePath.exists()) { Optional fileUrl = this.fileURIResolver.resolve(filePath); Optional thumbUrl = this.fileThumbnailURIResolver.resolve(filePath); @@ -57,16 +60,13 @@ public class FileMetadataService { try { for (Path child : filePath.getChildren()) { - if (child.getFilename().startsWith(".")) { + if (child.getFilename().startsWith(".") || + fileConfiguration.ignored().isPresent() && + fileConfiguration.ignored().get().stream() + .anyMatch(i -> child.getFilename().endsWith(i))) + { continue; } - if (fileConfiguration.ignored().isPresent()) { - for (String ignoreString : fileConfiguration.ignored().get()) { - if (child.getFilename().endsWith(ignoreString)) { - continue; - } - } - } Optional childFileUrl = this.fileURIResolver.resolve(child); Optional childThumbUrl = this.fileThumbnailURIResolver.resolve(child); @@ -85,8 +85,12 @@ public class FileMetadataService { contentInfo = new FolderInfo(child.getFilename(), childFileUrl.isPresent() ? childFileUrl.get() : ""); } else { - contentInfo = new FileInfo(child.getFilename(), - childFileUrl.isPresent() ? childFileUrl.get() : ""); + Optional childTokenUrl = this.fileTokenURIResolver.resolve(child); + contentInfo = new FileInfo( + child.getFilename(), + childFileUrl.isPresent() ? childFileUrl.get() : "", + childTokenUrl.isPresent() ? childTokenUrl.get() : "" + ); } if (childThumbUrl.isPresent()) { @@ -101,11 +105,12 @@ public class FileMetadataService { return folderInfo; } else { + Optional tokenUrl = this.fileTokenURIResolver.resolve(filePath); FileInfo fileInfo = new FileInfo( filePath.getFilename(), thumbUrl.isPresent() ? thumbUrl.get() : "", fileUrl.isPresent() ? fileUrl.get() : "", - "" + tokenUrl.isPresent() ? tokenUrl.get() : "" ); return fileInfo; diff --git a/src/main/java/sh/rhiobet/lalafin/file/resolver/FileTokenURIResolver.java b/src/main/java/sh/rhiobet/lalafin/file/resolver/FileTokenURIResolver.java new file mode 100644 index 0000000..3f3b495 --- /dev/null +++ b/src/main/java/sh/rhiobet/lalafin/file/resolver/FileTokenURIResolver.java @@ -0,0 +1,36 @@ +package sh.rhiobet.lalafin.file.resolver; + +import java.util.Optional; + +import org.jboss.resteasy.reactive.common.util.Encode; + +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; +import jakarta.inject.Named; +import sh.rhiobet.lalafin.core.path.model.Path; +import sh.rhiobet.lalafin.core.path.resolver.PathURIResolver; +import sh.rhiobet.lalafin.file.access.FileTokenProvider; + +@ApplicationScoped +@Named("file/resolver/token") +public class FileTokenURIResolver implements PathURIResolver { + @Inject + @Named("file/resolver") + PathURIResolver fileURIResolver; + + @Inject + FileTokenProvider fileTokenProvider; + + @Override + public Optional resolve(Path path) { + Optional fileURI = this.fileURIResolver.resolve(path); + + if (fileURI.isPresent()) { + return Optional.of( + "/v1/api/public/file/token/" + this.fileTokenProvider.getFileToken(fileURI.get()) + "/" + + Encode.encodePathSegment(path.getFilename())); + } + + return Optional.empty(); + } +}