diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Person.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Person.kt index c04ba736..cba9eeaf 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Person.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Person.kt @@ -20,6 +20,7 @@ constructor( var following: String? ) : Object(add(type, "Person")), HasId, HasName { + @Suppress("CyclomaticComplexMethod", "CognitiveComplexMethod") override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false @@ -43,6 +44,7 @@ constructor( return true } + @Suppress("CyclomaticComplexMethod") override fun hashCode(): Int { var result = super.hashCode() result = 31 * result + name.hashCode() diff --git a/src/main/kotlin/dev/usbharu/hideout/application/config/SecurityConfig.kt b/src/main/kotlin/dev/usbharu/hideout/application/config/SecurityConfig.kt index dead45f0..59caf58d 100644 --- a/src/main/kotlin/dev/usbharu/hideout/application/config/SecurityConfig.kt +++ b/src/main/kotlin/dev/usbharu/hideout/application/config/SecurityConfig.kt @@ -186,6 +186,9 @@ class SecurityConfig { authorize(POST, "/api/v1/accounts", permitAll) authorize("/auth/sign_up", hasRole("ANONYMOUS")) + authorize(GET, "/files", permitAll) + authorize(GET, "/users/*/icon.jpg", permitAll) + authorize(GET, "/users/*/header.jpg", permitAll) authorize(GET, "/api/v1/accounts/verify_credentials", hasAnyScope("read", "read:accounts")) diff --git a/src/main/kotlin/dev/usbharu/hideout/application/config/SpringConfig.kt b/src/main/kotlin/dev/usbharu/hideout/application/config/SpringConfig.kt index f3e088ab..c05229b7 100644 --- a/src/main/kotlin/dev/usbharu/hideout/application/config/SpringConfig.kt +++ b/src/main/kotlin/dev/usbharu/hideout/application/config/SpringConfig.kt @@ -42,7 +42,6 @@ data class S3StorageConfig( val secretKey: String ) - /** * メディアの保存にローカルファイルシステムを使用する際のコンフィグ * diff --git a/src/main/kotlin/dev/usbharu/hideout/core/interfaces/api/media/LocalFileController.kt b/src/main/kotlin/dev/usbharu/hideout/core/interfaces/api/media/LocalFileController.kt new file mode 100644 index 00000000..555cb592 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/core/interfaces/api/media/LocalFileController.kt @@ -0,0 +1,50 @@ +package dev.usbharu.hideout.core.interfaces.api.media + +import dev.usbharu.hideout.application.config.LocalStorageConfig +import dev.usbharu.hideout.core.service.media.FileTypeDeterminationService +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.core.io.ClassPathResource +import org.springframework.core.io.PathResource +import org.springframework.core.io.Resource +import org.springframework.http.MediaType +import org.springframework.http.ResponseEntity +import org.springframework.stereotype.Controller +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.PathVariable +import java.nio.file.Path +import kotlin.io.path.name + +@Controller +@ConditionalOnProperty("hideout.storage.type", havingValue = "local", matchIfMissing = true) +class LocalFileController( + localStorageConfig: LocalStorageConfig, + private val fileTypeDeterminationService: FileTypeDeterminationService +) { + + private val savePath = Path.of(localStorageConfig.path).toAbsolutePath() + + @GetMapping("/files/{id}") + fun files(@PathVariable("id") id: String): ResponseEntity { + val name = Path.of(id).name + val path = savePath.resolve(name) + + val mimeType = fileTypeDeterminationService.fileType(path, name) + val pathResource = PathResource(path) + + return ResponseEntity + .ok() + .contentType(MediaType(mimeType.type, mimeType.subtype)) + .contentLength(pathResource.contentLength()) + .body(pathResource) + } + + @GetMapping("/users/{user}/icon.jpg", "/users/{user}/header.jpg") + fun icons(): ResponseEntity { + val pathResource = ClassPathResource("icon.png") + return ResponseEntity + .ok() + .contentType(MediaType.IMAGE_PNG) + .contentLength(pathResource.contentLength()) + .body(pathResource) + } +} diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/media/LocalFileSystemMediaDataStore.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/media/LocalFileSystemMediaDataStore.kt index a7300081..412b50a5 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/media/LocalFileSystemMediaDataStore.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/service/media/LocalFileSystemMediaDataStore.kt @@ -12,8 +12,6 @@ import kotlin.io.path.createDirectories import kotlin.io.path.deleteIfExists import kotlin.io.path.outputStream -@Service -@ConditionalOnProperty("hideout.storage.type", havingValue = "local", matchIfMissing = true) /** * ローカルファイルシステムにメディアを保存します * @@ -23,8 +21,11 @@ import kotlin.io.path.outputStream * @param applicationConfig ApplicationConfig * @param localStorageConfig LocalStorageConfig */ +@Service +@ConditionalOnProperty("hideout.storage.type", havingValue = "local", matchIfMissing = true) class LocalFileSystemMediaDataStore( - applicationConfig: ApplicationConfig, localStorageConfig: LocalStorageConfig + applicationConfig: ApplicationConfig, + localStorageConfig: LocalStorageConfig ) : MediaDataStore { private val savePath: Path = Path.of(localStorageConfig.path).toAbsolutePath() @@ -39,7 +40,6 @@ class LocalFileSystemMediaDataStore( val fileSavePath = buildSavePath(savePath, dataMediaSave.name) val thumbnailSavePath = buildSavePath(savePath, "thumbnail-" + dataMediaSave.name) - dataMediaSave.thumbnailInputStream?.inputStream()?.use { it.buffered().use { bufferedInputStream -> thumbnailSavePath.outputStream(StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE) @@ -51,7 +51,6 @@ class LocalFileSystemMediaDataStore( } } - dataMediaSave.fileInputStream.inputStream().use { it.buffered().use { bufferedInputStream -> fileSavePath.outputStream(StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE) @@ -60,7 +59,9 @@ class LocalFileSystemMediaDataStore( } return SuccessSavedMedia( - dataMediaSave.name, publicUrl + dataMediaSave.name, publicUrl + "thumbnail-" + dataMediaSave.name + dataMediaSave.name, + publicUrl + dataMediaSave.name, + publicUrl + "thumbnail-" + dataMediaSave.name ) } @@ -82,7 +83,9 @@ class LocalFileSystemMediaDataStore( logger.info("SUCCESS Media upload. {}", dataSaveRequest.name) return SuccessSavedMedia( - dataSaveRequest.name, publicUrl + dataSaveRequest.name, publicUrl + "thumbnail-" + dataSaveRequest.name + dataSaveRequest.name, + publicUrl + dataSaveRequest.name, + publicUrl + "thumbnail-" + dataSaveRequest.name ) }