From 49929928301aa61a1cd83d91123986bd27d71892 Mon Sep 17 00:00:00 2001 From: belljun3395 <195850@jnu.ac.kr> Date: Fri, 13 Dec 2024 19:21:14 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20OpenApi3Task=EC=97=90=EC=84=9C=20multip?= =?UTF-8?q?art-form-data=20=EC=B6=94=EA=B0=80=20=EB=B0=8F=20security=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95=ED=95=98=EB=8F=84=EB=A1=9D=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/build.gradle.kts | 126 ++++++++++++++++++++++++------------------- 1 file changed, 72 insertions(+), 54 deletions(-) diff --git a/api/build.gradle.kts b/api/build.gradle.kts index 7c8e44a6d..1b9df922a 100644 --- a/api/build.gradle.kts +++ b/api/build.gradle.kts @@ -1,6 +1,13 @@ +import com.epages.restdocs.apispec.gradle.OpenApi3Task import org.springframework.boot.gradle.tasks.bundling.BootJar -import java.util.Random +import org.yaml.snakeyaml.DumperOptions +import org.yaml.snakeyaml.Yaml +import java.io.FileInputStream +import java.io.FileWriter +import java.io.InputStream +import java.util.* + tasks.withType(BootJar::class.java) { loaderImplementation = org.springframework.boot.loader.tools.LoaderImplementation.CLASSIC @@ -40,64 +47,75 @@ dependencies { implementation("org.jsoup:jsoup:1.15.3") } -tasks.named("generateStaticSwaggerUI") { +tasks.withType(OpenApi3Task::class.java) { + val multipartformdataPaths = listOf( + "/api/v1/admin/utilities/conversion/image", + "/api/v1/admin/utilities/conversion/content" + ) doLast { - val swaggerSpecSource = "$projectDir/src/main/resources/static/docs/${project.name}/swagger-ui/swagger-spec.js" - - file(swaggerSpecSource).writeText( - file(swaggerSpecSource).readText().replace( - "operationId\" : \"PutImageApi\",", - "operationId\" : \"PutImageApi\",\n" + - putImageRequestScriptSource - ) - ) - - file(swaggerSpecSource).writeText( - file(swaggerSpecSource).readText().replace( - "operationId\" : \"ConvertContentApi\",", - "operationId\" : \"ConvertContentApi\",\n" + - putContentRequestScriptSource + val input: InputStream = FileInputStream(File("$projectDir/src/main/resources/static/openapi3.yaml")) + val options = DumperOptions().apply { + defaultFlowStyle = DumperOptions.FlowStyle.BLOCK + isPrettyFlow = true + } + val yaml = Yaml(options) + val yamlData = yaml.loadAll(input) + for (data in yamlData) { + val content = data as MutableMap<*, *> + val paths = content["paths"] as MutableMap<*, *> + paths.forEach { (path, _methods) -> + val methods = _methods as MutableMap<*, *> + // Add security to paths that require Authorization header + methods.forEach { (_, _details) -> + val details = _details as MutableMap + if (details.containsKey("parameters")) { + val parameters = details["parameters"] as List> + parameters.forEach { param -> + if (param["name"] == "Authorization") { + details["security"] = listOf(mapOf("bearerAuth" to emptyList())) + } + } + } + } + + // Add requestBody for multipart/form-data paths + if (multipartformdataPaths.contains(path)) { + if (methods.containsKey("post")) { + val post = methods["post"] as MutableMap + if (!post.containsKey("requestBody")) { + post["requestBody"] = mutableMapOf( + "content" to mutableMapOf( + "multipart/form-data" to mutableMapOf( + "schema" to mutableMapOf( + "type" to "object", + "properties" to mutableMapOf( + "source" to mutableMapOf( + "type" to "string", + "format" to "binary" + ) + ) + ) + ) + ) + ) + } + } + } + } + val components = content["components"] as MutableMap> + components["securitySchemes"] = mutableMapOf( + "bearerAuth" to mutableMapOf( + "type" to "http", + "scheme" to "bearer", + "bearerFormat" to "JWT" + ) ) - ) + val output = File("$projectDir/src/main/resources/static/openapi3.yaml") + yaml.dump(content, FileWriter(output)) + } } } -val putImageRequestScriptSource = "" + - " \"requestBody\" : {\n" + - " \"content\" : {\n" + - " \"multipart/form-data\" : {\n" + - " \"schema\" : {\n" + - " \"type\" : \"object\",\n" + - " \"properties\" : {\n" + - " \"source\" : {\n" + - " \"type\" : \"string\",\n" + - " \"format\" : \"binary\"\n" + - " }\n" + - " }\n" + - "\n" + - " }\n" + - " }\n" + - " }\n" + - " }," - -val putContentRequestScriptSource = "" + - " \"requestBody\" : {\n" + - " \"content\" : {\n" + - " \"multipart/form-data\" : {\n" + - " \"schema\" : {\n" + - " \"type\" : \"object\",\n" + - " \"properties\" : {\n" + - " \"content\" : {\n" + - " \"type\" : \"string\",\n" + - " \"format\" : \"binary\"\n" + - " }\n" + - " }\n" + - "\n" + - " }\n" + - " }\n" + - " }\n" + - " }," - val imageName = project.hasProperty("imageName").let { if (it) { project.property("imageName") as String