Skip to content

Commit

Permalink
ref: Move jwt utils to jicoco. (#552)
Browse files Browse the repository at this point in the history
* ref: Move jwt utils to jicoco.

* squash: Remove stale comment.
  • Loading branch information
bgrozev authored Nov 13, 2024
1 parent 77dc5a9 commit 17ab5bd
Show file tree
Hide file tree
Showing 4 changed files with 10 additions and 234 deletions.
26 changes: 6 additions & 20 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@
<kotest.version>5.7.2</kotest.version>
<mockk.version>1.13.8</mockk.version>
<ktor.version>3.0.0</ktor.version>
<jwt.version>0.11.5</jwt.version>
<jicoco.version>1.1-143-g175c44b</jicoco.version>
<jicoco.version>1.1-145-g9a3479a</jicoco.version>
<jitsi.utils.version>1.0-127-g6c65524</jitsi.utils.version>
</properties>

Expand Down Expand Up @@ -57,6 +56,11 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>jicoco-jwt</artifactId>
<version>${jicoco.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
Expand Down Expand Up @@ -179,24 +183,6 @@
<artifactId>config</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>${jwt.version}</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>${jwt.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>${jwt.version}</version>
<scope>runtime</scope>
</dependency>

<!-- testing -->
<dependency>
<groupId>org.jitsi</groupId>
Expand Down
63 changes: 0 additions & 63 deletions src/main/kotlin/org/jitsi/jibri/util/RefreshingProperty.kt

This file was deleted.

75 changes: 4 additions & 71 deletions src/main/kotlin/org/jitsi/jibri/webhooks/v1/WebhookClient.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@

package org.jitsi.jibri.webhooks.v1

import com.typesafe.config.ConfigObject
import io.jsonwebtoken.Jwts
import io.jsonwebtoken.SignatureAlgorithm
import io.ktor.client.HttpClient
import io.ktor.client.engine.apache.Apache
import io.ktor.client.plugins.HttpRequestTimeoutException
Expand All @@ -37,29 +34,21 @@ import io.ktor.serialization.jackson.jackson
import kotlinx.coroutines.asCoroutineDispatcher
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import org.bouncycastle.openssl.PEMKeyPair
import org.bouncycastle.openssl.PEMParser
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter
import org.jitsi.jibri.config.Config
import org.jitsi.jibri.status.JibriSessionStatus
import org.jitsi.jibri.status.JibriStatus
import org.jitsi.jibri.util.RefreshingProperty
import org.jitsi.jibri.util.TaskPools
import org.jitsi.jwt.JwtInfo
import org.jitsi.jwt.RefreshingJwt
import org.jitsi.metaconfig.optionalconfig
import org.jitsi.utils.logging2.createLogger
import java.io.FileReader
import java.security.PrivateKey
import java.time.Clock
import java.time.Duration
import java.util.Date
import java.util.concurrent.CopyOnWriteArraySet

/**
* A client for notifying subscribers of Jibri events
*/
class WebhookClient(
private val jibriId: String,
private val clock: Clock = Clock.systemUTC(),
client: HttpClient = HttpClient(Apache)
) {
private val logger = createLogger()
Expand All @@ -68,19 +57,7 @@ class WebhookClient(
"jibri.jwt-info".from(Config.configSource)
.convertFrom(JwtInfo.Companion::fromConfig)
}

// We refresh 5 minutes before the expiration
private val jwt: String? by RefreshingProperty(jwtInfo?.ttl?.minus(Duration.ofMinutes(5)) ?: INFINITE) {
jwtInfo?.let {
Jwts.builder()
.setHeaderParam("kid", it.kid)
.setIssuer(it.issuer)
.setAudience(it.audience)
.setExpiration(Date.from(clock.instant().plus(it.ttl)))
.signWith(it.privateKey, SignatureAlgorithm.RS256)
.compact()
}
}
private val jwt: String? by RefreshingJwt(jwtInfo)

private val client = client.config {
expectSuccess = false
Expand All @@ -92,7 +69,7 @@ class WebhookClient(
}
jwt?.let {
defaultRequest {
bearerAuth("$jwt")
bearerAuth(it)
}
}
}
Expand Down Expand Up @@ -146,8 +123,6 @@ class WebhookClient(
}
}

private val INFINITE = Duration.ofSeconds(Long.MAX_VALUE)

/**
* Just like [HttpClient.post], but automatically sets the content type to
* [ContentType.Application.Json].
Expand All @@ -159,45 +134,3 @@ private suspend inline fun HttpClient.postJson(
block()
contentType(ContentType.Application.Json)
}

private data class JwtInfo(
val privateKey: PrivateKey,
val kid: String,
val issuer: String,
val audience: String,
val ttl: Duration
) {
companion object {
private val logger = createLogger()
fun fromConfig(jwtConfigObj: ConfigObject): JwtInfo {
// Any missing or incorrect value here will throw, which is what we want:
// If anything is wrong, we should fail to create the JwtInfo
val jwtConfig = jwtConfigObj.toConfig()
logger.info("got jwtConfig: ${jwtConfig.root().render()}")
try {
return JwtInfo(
privateKey = parseKeyFile(jwtConfig.getString("signing-key-path")),
kid = jwtConfig.getString("kid"),
issuer = jwtConfig.getString("issuer"),
audience = jwtConfig.getString("audience"),
ttl = jwtConfig.getDuration("ttl").withMinimum(Duration.ofMinutes(10))
)
} catch (t: Throwable) {
logger.info("Unable to create JwtInfo: $t")
throw t
}
}
}
}

private fun parseKeyFile(keyFilePath: String): PrivateKey {
val parser = PEMParser(FileReader(keyFilePath))
return (parser.readObject() as PEMKeyPair).let { pemKeyPair ->
JcaPEMKeyConverter().getKeyPair(pemKeyPair).private
}
}

/**
* Returns [min] if this Duration is less than that minimum, otherwise this
*/
private fun Duration.withMinimum(min: Duration): Duration = maxOf(this, min)
80 changes: 0 additions & 80 deletions src/test/kotlin/org/jitsi/jibri/util/RefreshingPropertyTest.kt

This file was deleted.

0 comments on commit 17ab5bd

Please sign in to comment.