-
Notifications
You must be signed in to change notification settings - Fork 643
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Replace Spray JWT dependency (#3030)
- Loading branch information
Showing
4 changed files
with
86 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
79 changes: 79 additions & 0 deletions
79
google-common/src/main/scala/akka/stream/alpakka/google/auth/JwtSprayJsonParser.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
/* | ||
* This software is licensed under the Apache 2 license. | ||
* Copyright 2021 JWT-Scala Contributors. | ||
* | ||
* Copyright (C) since 2023 Lightbend Inc. <https://www.lightbend.com> | ||
*/ | ||
|
||
package akka.stream.alpakka.google.auth | ||
|
||
import akka.annotation.InternalApi | ||
import pdi.jwt.{JwtAlgorithm, JwtClaim, JwtHeader, JwtJsonCommon} | ||
|
||
import java.time.Clock | ||
import pdi.jwt.exceptions.JwtNonStringException | ||
import spray.json._ | ||
|
||
/** | ||
* Implementation of `JwtCore` using `JsObject` from spray-json. | ||
* | ||
* This class originally came from jwt-spray-json, | ||
* but was removed in https://github.com/jwt-scala/jwt-scala/commit/bf1131ce02480103c0b953b97da001105a3ee038 | ||
*/ | ||
@InternalApi | ||
private[auth] trait JwtSprayJsonParser[H, C] extends JwtJsonCommon[JsObject, H, C] { | ||
protected def parse(value: String): JsObject = value.parseJson.asJsObject | ||
|
||
protected def stringify(value: JsObject): String = value.compactPrint | ||
|
||
protected def getAlgorithm(header: JsObject): Option[JwtAlgorithm] = | ||
header.fields.get("alg").flatMap { | ||
case JsString("none") => None | ||
case JsString(algo) => Option(JwtAlgorithm.fromString(algo)) | ||
case JsNull => None | ||
case _ => throw new JwtNonStringException("alg") | ||
} | ||
|
||
} | ||
|
||
@InternalApi | ||
private[auth] object JwtSprayJson extends JwtSprayJson(Clock.systemUTC) { | ||
def apply(clock: Clock): JwtSprayJson = new JwtSprayJson(clock) | ||
} | ||
|
||
@InternalApi | ||
private[auth] class JwtSprayJson(override val clock: Clock) extends JwtSprayJsonParser[JwtHeader, JwtClaim] { | ||
|
||
import DefaultJsonProtocol._ | ||
override def parseHeader(header: String): JwtHeader = { | ||
val jsObj = parse(header) | ||
JwtHeader( | ||
algorithm = getAlgorithm(jsObj), | ||
typ = safeGetField[String](jsObj, "typ"), | ||
contentType = safeGetField[String](jsObj, "cty"), | ||
keyId = safeGetField[String](jsObj, "kid") | ||
) | ||
} | ||
|
||
override def parseClaim(claim: String): JwtClaim = { | ||
val jsObj = parse(claim) | ||
val content = JsObject(jsObj.fields - "iss" - "sub" - "aud" - "exp" - "nbf" - "iat" - "jti") | ||
JwtClaim( | ||
content = stringify(content), | ||
issuer = safeGetField[String](jsObj, "iss"), | ||
subject = safeGetField[String](jsObj, "sub"), | ||
audience = safeGetField[Set[String]](jsObj, "aud") | ||
.orElse(safeGetField[String](jsObj, "aud").map(s => Set(s))), | ||
expiration = safeGetField[Long](jsObj, "exp"), | ||
notBefore = safeGetField[Long](jsObj, "nbf"), | ||
issuedAt = safeGetField[Long](jsObj, "iat"), | ||
jwtId = safeGetField[String](jsObj, "jti") | ||
) | ||
} | ||
|
||
private[this] def safeRead[A: JsonReader](js: JsValue) = | ||
safeReader[A].read(js).fold(_ => None, a => Option(a)) | ||
|
||
private[this] def safeGetField[A: JsonReader](js: JsObject, name: String) = | ||
js.fields.get(name).flatMap(safeRead[A]) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters