Skip to content

Commit

Permalink
feat: FCM TOKEN 수정 (#33)
Browse files Browse the repository at this point in the history
  • Loading branch information
devmizz authored Feb 13, 2025
1 parent 3e3a1a8 commit 34746dd
Show file tree
Hide file tree
Showing 10 changed files with 108 additions and 3 deletions.
2 changes: 2 additions & 0 deletions src/main/kotlin/co/yappuworld/global/config/SecurityConfig.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package co.yappuworld.global.config
import co.yappuworld.global.filter.JwtFilter
import co.yappuworld.global.security.SecurityPathMatchersManager.adminMatchers
import co.yappuworld.global.security.SecurityPathMatchersManager.anyoneMatchers
import co.yappuworld.global.security.SecurityPathMatchersManager.userMatchers
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.http.HttpMethod.DELETE
Expand Down Expand Up @@ -31,6 +32,7 @@ class SecurityConfig(
.sessionManagement { it.sessionCreationPolicy(STATELESS) }
.authorizeHttpRequests {
it.requestMatchers(adminMatchers).hasAnyRole("ADMIN")
.requestMatchers(userMatchers).hasAnyRole("ADMIN", "ALUMNI", "GRADUATE", "ACTIVE")
.requestMatchers(anyoneMatchers).permitAll()
}
.authorizeHttpRequests { it.anyRequest().permitAll() }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ object SecurityPathMatchersManager {
antMatcher(GET, "/v1/positions")
)

val userMatchers = RequestMatchers.anyOf(
antMatcher("/v1/users/fcm")
)

val adminMatchers = RequestMatchers.anyOf(
antMatcher(POST, "/v1/admin/**"),
antMatcher(POST, "/v1/admin/auth/application/reject")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import co.yappuworld.user.application.dto.response.UserAlarmStatusAppResponse
import co.yappuworld.user.domain.model.UserAlarmSetting
import co.yappuworld.user.domain.vo.UserError
import co.yappuworld.user.infrastructure.UserAlarmSettingRepository
import co.yappuworld.user.infrastructure.UserDeviceRepository
import io.github.oshai.kotlinlogging.KotlinLogging
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
Expand All @@ -16,7 +17,8 @@ private val logger = KotlinLogging.logger { }

@Service
class UserAlarmService(
private val userAlarmSettingRepository: UserAlarmSettingRepository
private val userAlarmSettingRepository: UserAlarmSettingRepository,
private val userDeviceRepository: UserDeviceRepository
) {

@Transactional(readOnly = true)
Expand All @@ -42,6 +44,17 @@ class UserAlarmService(
return MasterAlarmToggleAppResponse(setting.master)
}

@Transactional
fun updateFcmToken(
userId: UUID,
fcmToken: String
) {
userDeviceRepository.findUserDeviceOrNullByUserId(userId)
?.apply { updateFcmToken(fcmToken) }
?.also { userDeviceRepository.save(it) }
?: throw BusinessException(UserError.USER_RELATED_DATA_NOT_FOUND)
}

private fun getUserAlarmSetting(userId: UUID): UserAlarmSetting {
return userAlarmSettingRepository.findUserAlarmSettingOrNullByUserId(userId)
?: run {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,15 @@ import java.util.UUID
@Table("user_devices")
class UserDevice private constructor(
val userId: UUID,
val fcmToken: String,
fcmToken: String?,
@Id
@JvmField
val id: UUID
) : BaseEntity(), Persistable<UUID> {

var fcmToken: String? = fcmToken
private set

constructor(userId: UUID, fcmToken: String) : this(userId, fcmToken, UlidCreator.getMonotonicUlid().toUuid())

fun withId(id: UUID): UserDevice {
Expand All @@ -29,4 +32,8 @@ class UserDevice private constructor(
override fun isNew(): Boolean {
return !isCreatedAtInitialized()
}

fun updateFcmToken(fcmToken: String) {
this.fcmToken = fcmToken
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,7 @@ import co.yappuworld.user.domain.model.UserDevice
import org.springframework.data.repository.CrudRepository
import java.util.UUID

interface UserDeviceRepository : CrudRepository<UserDevice, UUID>
interface UserDeviceRepository : CrudRepository<UserDevice, UUID> {

fun findUserDeviceOrNullByUserId(userId: UUID): UserDevice?
}
34 changes: 34 additions & 0 deletions src/main/kotlin/co/yappuworld/user/presentation/UserSystemApi.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package co.yappuworld.user.presentation

import co.yappuworld.global.security.SecurityUser
import co.yappuworld.user.presentation.dto.request.UpdateFcmTokenApiRequestDto
import io.swagger.v3.oas.annotations.Operation
import io.swagger.v3.oas.annotations.media.Content
import io.swagger.v3.oas.annotations.responses.ApiResponse
import io.swagger.v3.oas.annotations.responses.ApiResponses
import io.swagger.v3.oas.annotations.tags.Tag
import jakarta.validation.Valid
import org.springframework.http.ResponseEntity
import org.springframework.security.core.annotation.AuthenticationPrincipal
import org.springframework.web.bind.annotation.PutMapping
import org.springframework.web.bind.annotation.RequestBody

@Tag(name = "유저 시스템 설정 관련 API", description = "FCM, 기기 정보 등..")
interface UserSystemApi {

@Operation(summary = "FCM 토큰 수정")
@ApiResponses(
value = [
ApiResponse(
description = "FCM 토큰 수정 성공",
responseCode = "204",
content = [Content(examples = emptyArray())]
)
]
)
@PutMapping("/v1/users/fcm")
fun updateFcmToken(
@AuthenticationPrincipal securityUser: SecurityUser,
@Valid @RequestBody request: UpdateFcmTokenApiRequestDto
): ResponseEntity<Unit>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package co.yappuworld.user.presentation

import co.yappuworld.global.security.SecurityUser
import co.yappuworld.user.application.UserAlarmService
import co.yappuworld.user.presentation.dto.request.UpdateFcmTokenApiRequestDto
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.RestController

@RestController
class UserSystemController(
private val userAlarmService: UserAlarmService
) : UserSystemApi {

override fun updateFcmToken(
securityUser: SecurityUser,
request: UpdateFcmTokenApiRequestDto
): ResponseEntity<Unit> {
userAlarmService.updateFcmToken(securityUser.userId, request.fcmToken)
return ResponseEntity.noContent().build()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package co.yappuworld.user.presentation.dto.request

import io.swagger.v3.oas.annotations.media.Schema
import jakarta.validation.constraints.NotNull

data class UpdateFcmTokenApiRequestDto(
@Schema(description = "FCM 토큰")
@field:NotNull(message = "FCM TOKEN 값으로 NULL은 허용되지 않습니다.")
val fcmToken: String
)
10 changes: 10 additions & 0 deletions src/main/resources/schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,13 @@ CREATE TABLE user_alarm_settings
device tinyint(1) NOT NULL,
master tinyint(1) NOT NULL
);

DROP TABLE IF EXISTS user_devices;
CREATE TABLE user_devices
(
id varchar(36) PRIMARY KEY,
created_at datetime,
updated_at datetime,
user_id varchar(36) NOT NULL,
fcm_token varchar(128) NOT NULL
);
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class ApplicationDetailsRepositoryConverterTest {
it.reject("거절")
userSignUpApplicationRepository.save(it)
}

val secondApplication = SignUpApplication(firstDetails).also {
userSignUpApplicationRepository.save(it)
}
Expand Down

0 comments on commit 34746dd

Please sign in to comment.