Skip to content

Commit 5b5de62

Browse files
authored
Add admin authentication for version updates and enhance AppVersionService (#44)
1 parent a7e6afa commit 5b5de62

10 files changed

Lines changed: 93 additions & 2 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package com.moa.common.auth
2+
3+
@Target(AnnotationTarget.FUNCTION)
4+
@Retention(AnnotationRetention.RUNTIME)
5+
annotation class AdminAuth
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package com.moa.common.auth
2+
3+
import com.moa.common.exception.UnauthorizedException
4+
import jakarta.servlet.http.HttpServletRequest
5+
import jakarta.servlet.http.HttpServletResponse
6+
import org.springframework.stereotype.Component
7+
import org.springframework.web.method.HandlerMethod
8+
import org.springframework.web.servlet.HandlerInterceptor
9+
10+
@Component
11+
class AdminAuthInterceptor(
12+
private val adminProperties: AdminProperties,
13+
) : HandlerInterceptor {
14+
15+
override fun preHandle(request: HttpServletRequest, response: HttpServletResponse, handler: Any): Boolean {
16+
if (handler is HandlerMethod && handler.hasMethodAnnotation(AdminAuth::class.java)) {
17+
val key = request.getHeader(ADMIN_KEY_HEADER)
18+
if (key != adminProperties.apiKey) {
19+
throw UnauthorizedException()
20+
}
21+
}
22+
return true
23+
}
24+
25+
companion object {
26+
private const val ADMIN_KEY_HEADER = "X-Admin-Key"
27+
}
28+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package com.moa.common.auth
2+
3+
import org.springframework.boot.context.properties.ConfigurationProperties
4+
5+
@ConfigurationProperties(prefix = "admin")
6+
data class AdminProperties(
7+
val apiKey: String,
8+
)

src/main/kotlin/com/moa/common/config/SwaggerConfig.kt

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,17 @@ class SwaggerConfig {
3535
.bearerFormat(jwt)
3636
.`in`(SecurityScheme.In.HEADER)
3737

38+
val adminKeyScheme = SecurityScheme()
39+
.name("X-Admin-Key")
40+
.type(SecurityScheme.Type.APIKEY)
41+
.`in`(SecurityScheme.In.HEADER)
42+
3843
return OpenAPI()
39-
.components(Components().addSecuritySchemes(securitySchemeName, securityScheme))
44+
.components(
45+
Components()
46+
.addSecuritySchemes(securitySchemeName, securityScheme)
47+
.addSecuritySchemes("AdminKey", adminKeyScheme)
48+
)
4049
.addSecurityItem(securityRequirement)
4150
.servers(
4251
listOf(

src/main/kotlin/com/moa/common/config/WebConfig.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,24 @@
11
package com.moa.common.config
22

3+
import com.moa.common.auth.AdminAuthInterceptor
34
import com.moa.common.auth.AuthMemberResolver
45
import com.moa.common.auth.OnboardingAuthMemberResolver
56
import org.springframework.context.annotation.Configuration
67
import org.springframework.web.method.support.HandlerMethodArgumentResolver
8+
import org.springframework.web.servlet.config.annotation.InterceptorRegistry
79
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer
810

911
@Configuration
1012
class WebConfig(
1113
private val onboardingAuthMemberResolver: OnboardingAuthMemberResolver,
1214
private val authMemberResolver: AuthMemberResolver,
15+
private val adminAuthInterceptor: AdminAuthInterceptor,
1316
) : WebMvcConfigurer {
1417

18+
override fun addInterceptors(registry: InterceptorRegistry) {
19+
registry.addInterceptor(adminAuthInterceptor)
20+
}
21+
1522
override fun addArgumentResolvers(resolvers: MutableList<HandlerMethodArgumentResolver>) {
1623
resolvers.add(onboardingAuthMemberResolver)
1724
resolvers.add(authMemberResolver)

src/main/kotlin/com/moa/controller/VersionController.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
package com.moa.controller
22

3+
import com.moa.common.auth.AdminAuth
34
import com.moa.common.response.ApiResponse
45
import com.moa.entity.OsType
56
import com.moa.service.AppVersionService
7+
import com.moa.service.dto.AppVersionUpdateRequest
8+
import io.swagger.v3.oas.annotations.security.SecurityRequirement
69
import io.swagger.v3.oas.annotations.tags.Tag
710
import org.springframework.web.bind.annotation.GetMapping
11+
import org.springframework.web.bind.annotation.PutMapping
12+
import org.springframework.web.bind.annotation.RequestBody
813
import org.springframework.web.bind.annotation.RequestMapping
914
import org.springframework.web.bind.annotation.RequestParam
1015
import org.springframework.web.bind.annotation.RestController
@@ -19,4 +24,10 @@ class VersionController(
1924
@GetMapping
2025
fun getVersion(@RequestParam osType: OsType) =
2126
ApiResponse.success(appVersionService.getVersion(osType))
27+
28+
@AdminAuth
29+
@SecurityRequirement(name = "AdminKey")
30+
@PutMapping
31+
fun updateVersion(@RequestBody request: AppVersionUpdateRequest) =
32+
ApiResponse.success(appVersionService.updateVersion(request))
2233
}

src/main/kotlin/com/moa/service/AppVersionService.kt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import com.moa.common.exception.NotFoundException
44
import com.moa.entity.OsType
55
import com.moa.repository.AppVersionRepository
66
import com.moa.service.dto.AppVersionResponse
7+
import com.moa.service.dto.AppVersionUpdateRequest
78
import org.springframework.stereotype.Service
89
import org.springframework.transaction.annotation.Transactional
910

@@ -21,4 +22,16 @@ class AppVersionService(
2122
minimumVersion = version.minimumVersion,
2223
)
2324
}
25+
26+
@Transactional
27+
fun updateVersion(request: AppVersionUpdateRequest): AppVersionResponse {
28+
val version = appVersionRepository.findByOsType(request.osType)
29+
?: throw NotFoundException()
30+
version.latestVersion = request.latestVersion
31+
version.minimumVersion = request.minimumVersion
32+
return AppVersionResponse(
33+
latestVersion = version.latestVersion,
34+
minimumVersion = version.minimumVersion,
35+
)
36+
}
2437
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.moa.service.dto
2+
3+
import com.moa.entity.OsType
4+
5+
data class AppVersionUpdateRequest(
6+
val osType: OsType,
7+
val latestVersion: String,
8+
val minimumVersion: String,
9+
)

src/main/resources/application.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ spring:
44
- moa-secret/oauth.yml
55
- moa-secret/jwt.yml
66
- moa-secret/db.yml
7+
- moa-secret/admin.yml
78

89
profiles:
910
default: local

src/main/resources/moa-secret

0 commit comments

Comments
 (0)