Skip to content

Commit

Permalink
Merge pull request #1 from team-onui/feture
Browse files Browse the repository at this point in the history
🔀 :: feture to develop
  • Loading branch information
gurdl0525 authored Nov 9, 2023
2 parents 313b816 + d39940e commit 0968b8a
Show file tree
Hide file tree
Showing 59 changed files with 543 additions and 371 deletions.
24 changes: 6 additions & 18 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,13 @@ jobs:

steps:
- uses: actions/checkout@v3

- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'zulu'

- name: Run ktlint
run: ./gradlew ktlintCheck

- name: Set up application.yml
run: |
mkdir -p src/main/resources
echo "${{ secrets.MAIN_APPLICATION }}" | base64 --decode > src/main/resources/application.yml
mkdir -p src/test/resources
echo "${{ secrets.TEST_APPLICATION }}" | base64 --decode > src/test/resources/application.yml
- name: run test
run: ./gradlew test

- name: run build
run: ./gradlew clean build -x test
distribution: 'temurin'

- name: Build with Gradle
uses: gradle/gradle-build-action@bd5760595778326ba7f1441bcf7e88b49de61a25 # v2.6.0
with:
arguments: build
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,4 @@ out/
.env

### copose ###
Docker-compose.yml
Docker-compose.yml
2 changes: 1 addition & 1 deletion src/main/kotlin/com/example/onui/OnuiApplication.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.context.properties.ConfigurationPropertiesScan
import org.springframework.boot.runApplication

@ConfigurationPropertiesScan
@ConfigurationPropertiesScan(basePackages = ["com.example.onui.global.env"])
@SpringBootApplication
class OnuiApplication

Expand Down
Original file line number Diff line number Diff line change
@@ -1,34 +1,36 @@
package com.example.onui.domain.auth.presentation

import com.example.onui.domain.auth.presentation.dto.request.ReissueRequest
import com.example.onui.domain.auth.presentation.dto.response.OauthLinkResponse
import com.example.onui.domain.auth.presentation.dto.response.TokenResponse
import com.example.onui.domain.auth.service.AppleAuthService
import com.example.onui.domain.auth.service.AuthService
import com.example.onui.domain.auth.service.GoogleAuthService
import org.springframework.validation.annotation.Validated
import org.springframework.web.bind.annotation.*
import javax.validation.Valid

@Validated
@RestController
@RequestMapping("/auth")
class AuthController(
private val googleAuthService: GoogleAuthService,
private val authService: AuthService
private val authService: AuthService,
private val appleAuthService: AppleAuthService
) {

@GetMapping("/google/link")
fun getGoogleClientId(): OauthLinkResponse = googleAuthService.getGoogleLoginLink()

@GetMapping("/oauth/google/token")
@GetMapping("/google")
fun oauthSignIn(
@RequestParam(name = "code", required = true)
code: String
): TokenResponse = googleAuthService.oauthGoogleSignIn(code)
@RequestParam(name = "token", required = true)
token: String
): TokenResponse = googleAuthService.oauthGoogleSignIn(token)

@PutMapping("/token")
@PutMapping("/re-issue")
fun reissue(
@RequestBody @Valid
req: ReissueRequest
): TokenResponse = authService.reissue(req.refreshToken!!)
@RequestParam("token", required = true)
token: String
): TokenResponse = authService.reissue(token)

@PostMapping("/apple")
fun oauthSignInWithApple(
@RequestParam(name = "token", required = true)
token: String
) = appleAuthService.signUp(token)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.example.onui.domain.auth.presentation.dto.request

data class AppleTokenRequest(
val clientId: String,
val clientSecret: String,
val code: String,
val redirectUri: String,
val grantType: String = "authorization_code"
)

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.example.onui.domain.auth.service

interface AppleAuthService {

fun signUp(idToken: String): Any
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package com.example.onui.domain.auth.service

import com.example.onui.domain.auth.presentation.dto.response.TokenResponse
import com.example.onui.domain.user.entity.User
import com.example.onui.domain.user.repository.UserRepository
import com.example.onui.global.config.error.exception.ExpiredTokenException
import com.example.onui.global.config.error.exception.InvalidTokenException
import com.example.onui.global.config.jwt.AppleJwtParser
import com.example.onui.global.config.jwt.TokenProvider
import com.example.onui.infra.feign.apple.AppleClient
import com.example.onui.infra.feign.apple.dto.ApplePublicKey
import com.example.onui.infra.feign.apple.dto.ApplePublicKeys
import io.jsonwebtoken.Claims
import io.jsonwebtoken.ExpiredJwtException
import io.jsonwebtoken.Jwts
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import java.security.KeyFactory
import java.security.NoSuchAlgorithmException
import java.security.PublicKey
import java.security.spec.InvalidKeySpecException
import java.util.*


@Service
class AppleAuthServiceImpl(
private val appleClient: AppleClient,
private val jwtProvider: TokenProvider,
private val jwtParser: AppleJwtParser,
private val userRepository: UserRepository
) : AppleAuthService {

private companion object {
const val ALG_HEADER_KEY = "alg"
const val KID_HEADER_KEY = "kid"
const val NAME = "user-"
}

@Transactional
override fun signUp(idToken: String): TokenResponse {

val token = parseIdToken(idToken)

val sub = token.subject


val user = userRepository.findBySub(sub)
?: userRepository.save(
User(
sub,
token.get("email", String::class.java)
?: (NAME + UUID.randomUUID().toString().replace("-", ""))
)
)

return jwtProvider.receiveToken(user.sub)
}

private fun parseIdToken(idToken: String) = parseClaims(
idToken, generatePublicKey(jwtParser.parseHeaders(idToken), appleClient.applePublicKeys())
)

private fun generatePublicKey(
tokenHeaders: MutableMap<String?, String?>,
applePublicKeys: ApplePublicKeys
): PublicKey {

val publicKey: ApplePublicKey =
applePublicKeys.matchesKey(tokenHeaders[ALG_HEADER_KEY]!!, tokenHeaders[KID_HEADER_KEY]!!)
?: throw InvalidTokenException

return try {
KeyFactory.getInstance(publicKey.kty).generatePublic(publicKey.publicKeySpec())
} catch (e: NoSuchAlgorithmException) {
throw IllegalStateException("Apple OAuth 로그인 중 public key 생성에 문제가 발생했습니다.")
} catch (e: InvalidKeySpecException) {
throw IllegalStateException("Apple OAuth 로그인 중 public key 생성에 문제가 발생했습니다.")
}
}

private fun parseClaims(token: String, publicKey: PublicKey): Claims {
return try {
Jwts.parser()
.setSigningKey(publicKey)
.parseClaimsJws(token)
.body
} catch (e: Exception) {
when (e) {
is ExpiredJwtException -> throw ExpiredTokenException
else -> throw InvalidTokenException
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
package com.example.onui.domain.auth.service

import com.example.onui.domain.auth.presentation.dto.response.OauthLinkResponse
import com.example.onui.domain.auth.presentation.dto.response.TokenResponse

interface GoogleAuthService {

fun getGoogleLoginLink(): OauthLinkResponse

fun oauthGoogleSignIn(code: String): TokenResponse
fun oauthGoogleSignIn(token: String): TokenResponse
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
package com.example.onui.domain.auth.service

import com.example.onui.domain.auth.presentation.dto.response.OauthLinkResponse
import com.example.onui.domain.auth.presentation.dto.response.TokenResponse
import com.example.onui.domain.auth.repository.RefreshTokenRepository
import com.example.onui.domain.user.entity.User
import com.example.onui.domain.user.repository.UserRepository
import com.example.onui.global.config.jwt.TokenProvider
import com.example.onui.infra.feign.google.GoogleAuthClient
import com.example.onui.infra.feign.google.GoogleInfoClient
import com.example.onui.infra.feign.google.env.GoogleProperty
import mu.KotlinLogging
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
Expand All @@ -18,42 +16,22 @@ import org.springframework.transaction.annotation.Transactional
class GoogleAuthServiceImpl(
private val googleAuth: GoogleAuthClient,
private val googleInfo: GoogleInfoClient,
private val googleProperty: GoogleProperty,
private val userRepository: UserRepository,
private val tokenProvider: TokenProvider,
private val refreshTokenRepository: RefreshTokenRepository
): GoogleAuthService {
) : GoogleAuthService {

private companion object {
const val GOOGLE_URL = "%s" +
"?client_id=%s" +
"&redirect_uri=%s" +
"&response_type=code&scope=https://www.googleapis.com/auth/userinfo.email+https://www.googleapis.com/auth/userinfo.profile"
const val ALT = "json"
const val GRANT_TYPE = "authorization_code"
val logger = KotlinLogging.logger{}
val logger = KotlinLogging.logger {}
}

override fun getGoogleLoginLink() = OauthLinkResponse(
GOOGLE_URL.format(
googleProperty.baseUrl,
googleProperty.clientId,
googleProperty.redirectUrl
)
)

@Transactional
override fun oauthGoogleSignIn(code: String): TokenResponse {
override fun oauthGoogleSignIn(token: String): TokenResponse {

val accessToken = googleAuth.googleAuth(
code,
googleProperty.clientId,
googleProperty.clientSecret,
googleProperty.redirectUrl,
GRANT_TYPE
).accessToken
logger.info { token }

val response = googleInfo.googleInfo(ALT, accessToken)
val response = googleInfo.googleInfo(ALT, token)

refreshTokenRepository.findBySub(response.sub)?.let {
refreshTokenRepository.delete(it)
Expand All @@ -62,10 +40,14 @@ class GoogleAuthServiceImpl(
val tokenResponse = tokenProvider.receiveToken(response.sub)

userRepository.findBySub(response.sub)
?: userRepository.save(User(
response.sub,
response.name
))
?: userRepository.save(
User(
response.sub,
response.name
)
)

googleAuth.revokeToken(token)

return tokenResponse
}
Expand Down
19 changes: 7 additions & 12 deletions src/main/kotlin/com/example/onui/domain/diary/entity/Diary.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@ import javax.persistence.*
class
Diary(
user: User,
title: String,
content: String,
content: String?,
mood: Mood,
tag: MutableList<String>,
createdAt: LocalDateTime,
image: String? = null,
id: UUID? = null
): BaseTimeEntity(createdAt) {
) : BaseTimeEntity(createdAt) {

@Id @GeneratedValue(strategy = GenerationType.AUTO)
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(columnDefinition = "BINARY(16)", nullable = false)
var id: UUID? = id
protected set
Expand All @@ -31,12 +31,8 @@ Diary(
var user: User = user
protected set

@Column(name = "title", length = 30, nullable = false)
var title: String= title
protected set

@Column(name = "content", length = 1500, nullable = false)
var content: String = content
@Column(name = "content", length = 1500)
var content: String? = content
protected set

@Column(name = "mood", nullable = false)
Expand All @@ -45,7 +41,7 @@ Diary(
protected set

@ElementCollection(fetch = FetchType.EAGER)
@CollectionTable(name = "diary_tag", joinColumns = [JoinColumn(name= "diary_id", referencedColumnName = "id")])
@CollectionTable(name = "diary_tag", joinColumns = [JoinColumn(name = "diary_id", referencedColumnName = "id")])
var tag: MutableList<String> = tag
protected set

Expand All @@ -61,7 +57,6 @@ Diary(

fun toDetailResponse() = DiaryDetailResponse(
this.id!!,
this.title,
this.content,
this.mood,
this.tag,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.example.onui.domain.diary.entity

enum class Mood(
coast: Int
val coast: Int
) {
WORST(-10),
BAD(-5),
Expand Down
Loading

0 comments on commit 0968b8a

Please sign in to comment.