Skip to content

Commit

Permalink
CID-3153: Improve JWT generation failure logging
Browse files Browse the repository at this point in the history
  • Loading branch information
mohamedlajmileanix committed Nov 19, 2024
1 parent 53dec5f commit 8835f42
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class GlobalExceptionHandler(

@ExceptionHandler(Exception::class)
fun handleUncaughtException(exception: Exception): ProblemDetail {
val detail = "An unexpected error occurred ${exception.message}"
val detail = "An unexpected error occurred. ${exception.message}"
val problemDetail = ProblemDetail.forStatusAndDetail(HttpStatus.INTERNAL_SERVER_ERROR, detail)
problemDetail.title = exception.message
exceptionLogger.error("Uncaught exception: ${exception.message}", exception)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import java.nio.file.Files
import java.security.KeyFactory
import java.security.PrivateKey
import java.security.Security
import java.security.spec.InvalidKeySpecException
import java.security.spec.PKCS8EncodedKeySpec
import java.util.*

Expand Down Expand Up @@ -49,32 +48,52 @@ class GitHubAuthenticationService(
fun generateAndCacheJwtToken() {
runCatching {
logger.info("Generating JWT token")
val privateKey = loadPrivateKey()
val jwt = createJwtToken(privateKey)
verifyAndCacheJwtToken(jwt)
}.onFailure {
logger.error("Failed to generate a valid jwt token", it)
throw it
}
}

private fun loadPrivateKey(): PrivateKey {
return runCatching {
Security.addProvider(BouncyCastleProvider())
val rsaPrivateKey: String = readPrivateKey()
val keySpec = PKCS8EncodedKeySpec(Base64.getDecoder().decode(rsaPrivateKey))
val privateKey = KeyFactory.getInstance("RSA").generatePrivate(keySpec)
val jwt = createJwtToken(privateKey)
gitHubEnterpriseService.verifyJwt(jwt.getOrThrow())
cachingService.set("jwtToken", jwt.getOrThrow(), JWT_EXPIRATION_DURATION)
}.onFailure {
if (it is InvalidKeySpecException) {
throw IllegalArgumentException("The provided private key is not in a valid PKCS8 format.", it)
} else {
throw it
}
KeyFactory.getInstance("RSA").generatePrivate(keySpec)
}.getOrElse {
logger.error("Failed to load private key", it)
throw IllegalArgumentException(
"Failed to load private key, " +
"the provided private key is not a valid PKCS8 key."
)
}
}

private fun createJwtToken(privateKey: PrivateKey): Result<String> {
private fun createJwtToken(privateKey: PrivateKey): String {
return runCatching {
Jwts.builder()
.setIssuedAt(Date())
.setExpiration(Date(System.currentTimeMillis() + JWT_EXPIRATION_DURATION))
.setIssuer(cachingService.get("githubAppId").toString())
.signWith(privateKey, SignatureAlgorithm.RS256)
.compact()
}.getOrElse {
logger.error("Failed to generate a JWT token", it)
throw FailedToCreateJWTException("Failed to generate a JWT token")
}
}

private fun verifyAndCacheJwtToken(jwt: String) {
runCatching {
gitHubEnterpriseService.verifyJwt(jwt)
cachingService.set("jwtToken", jwt, JWT_EXPIRATION_DURATION)
logger.info("JWT token generated and cached successfully")
}.onFailure {
throw FailedToCreateJWTException("Failed to generate a valid JWT token")
logger.error("Failed to verify and cache JWT token", it)
throw it
}
}

Expand Down

0 comments on commit 8835f42

Please sign in to comment.