mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-11 18:29:05 +01:00
[headless] Let websocket upgrade requests pass in AccessManager
This is because JavaScript in browsers apparently can not add Authentication headers to websocket requests, so we use a dedicated authentication message there. In Javalin 3, the AccessManager also handles websocket requests. We need to let those pass to support JavaScript.
This commit is contained in:
@@ -14,7 +14,7 @@ dependencies {
|
||||
implementation project(path: ':briar-core', configuration: 'default')
|
||||
implementation project(path: ':bramble-java', configuration: 'default')
|
||||
|
||||
implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.40'
|
||||
implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.40'
|
||||
implementation 'io.javalin:javalin:3.5.0'
|
||||
implementation 'org.slf4j:slf4j-simple:1.7.26'
|
||||
implementation 'com.fasterxml.jackson.core:jackson-databind:2.10.0'
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.fasterxml.jackson.core.JsonParseException
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import io.javalin.Javalin
|
||||
import io.javalin.apibuilder.ApiBuilder.*
|
||||
import io.javalin.core.security.AccessManager
|
||||
import io.javalin.core.util.Header.AUTHORIZATION
|
||||
import io.javalin.http.BadRequestResponse
|
||||
import io.javalin.http.Context
|
||||
@@ -23,6 +24,9 @@ import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
import kotlin.system.exitProcess
|
||||
|
||||
private const val VERSION = "v1"
|
||||
private const val WS = "/$VERSION/ws"
|
||||
|
||||
@Immutable
|
||||
@Singleton
|
||||
internal class Router
|
||||
@@ -39,27 +43,29 @@ constructor(
|
||||
private val logger = getLogger(Router::javaClass.name)
|
||||
private val stopped = AtomicBoolean(false)
|
||||
|
||||
internal fun start(authToken: String, port: Int, debug: Boolean) : Javalin {
|
||||
internal fun start(authToken: String, port: Int, debug: Boolean): Javalin {
|
||||
briarService.start()
|
||||
getRuntime().addShutdownHook(Thread(this::stop))
|
||||
|
||||
val accessManager = AccessManager { handler, ctx, _ ->
|
||||
when {
|
||||
ctx.header(AUTHORIZATION) == "Bearer $authToken" -> handler.handle(ctx)
|
||||
ctx.matchedPath() == WS -> handler.handle(ctx) // websockets use their own auth
|
||||
else -> ctx.status(401).result("Unauthorized")
|
||||
}
|
||||
}
|
||||
|
||||
val app = Javalin.create { config ->
|
||||
config.showJavalinBanner = false
|
||||
config.accessManager { handler, ctx, _ ->
|
||||
if (ctx.header(AUTHORIZATION) == "Bearer $authToken") {
|
||||
handler.handle(ctx)
|
||||
} else {
|
||||
ctx.status(401).result("Unauthorized")
|
||||
}
|
||||
}
|
||||
config.accessManager(accessManager)
|
||||
if (debug) config.enableDevLogging()
|
||||
}.events {event ->
|
||||
}.events { event ->
|
||||
event.serverStartFailed { serverStopped() }
|
||||
event.serverStopped { serverStopped() }
|
||||
}
|
||||
|
||||
app.routes {
|
||||
path("/v1") {
|
||||
path("/$VERSION") {
|
||||
path("/contacts") {
|
||||
get { ctx -> contactController.list(ctx) }
|
||||
path("add") {
|
||||
@@ -92,7 +98,7 @@ constructor(
|
||||
}
|
||||
}
|
||||
}
|
||||
app.ws("/v1/ws") { ws ->
|
||||
app.ws(WS) { ws ->
|
||||
if (logger.isLoggable(INFO)) ws.onConnect { ctx ->
|
||||
logger.info("Received websocket connection from ${ctx.session.remoteAddress}")
|
||||
logger.info("Waiting for authentication")
|
||||
@@ -147,7 +153,7 @@ fun Context.getContactIdFromPathParam(): ContactId {
|
||||
/**
|
||||
* Returns a String from the JSON field or throws [BadRequestResponse] if null or empty.
|
||||
*/
|
||||
fun Context.getFromJson(objectMapper: ObjectMapper, field: String) : String {
|
||||
fun Context.getFromJson(objectMapper: ObjectMapper, field: String): String {
|
||||
try {
|
||||
val jsonNode = objectMapper.readTree(body())
|
||||
if (!jsonNode.hasNonNull(field)) throw BadRequestResponse("'$field' missing in JSON")
|
||||
|
||||
@@ -77,7 +77,7 @@ dependencyVerification {
|
||||
'org.jetbrains.kotlin:kotlin-stdlib-common:1.3.40:kotlin-stdlib-common-1.3.40.jar:5f551a3ffe7683f4741d96fdc49835864aa08ddfc63d38109884973e19eed1cb',
|
||||
'org.jetbrains.kotlin:kotlin-stdlib-common:1.3.50:kotlin-stdlib-common-1.3.50.jar:8ce678e88e4ba018b66dacecf952471e4d7dfee156a8a819760a5a5ff29d323c',
|
||||
'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.40:kotlin-stdlib-jdk7-1.3.40.jar:f79d84613679095d17518dd8fb4249183f334cf80e4d7a25a7e0ed519ee993ab',
|
||||
'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.31:kotlin-stdlib-jdk8-1.3.31.jar:ad6acd219b468a532ac3b3c5aacbfd5db02d0ffcf967e2113e4677e2429490f6',
|
||||
'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.40:kotlin-stdlib-jdk8-1.3.40.jar:05e11f693719aa515e6946f51eacc88cb53437cc685d914c114f090792ba9ba1',
|
||||
'org.jetbrains.kotlin:kotlin-stdlib:1.3.40:kotlin-stdlib-1.3.40.jar:f76f9812a703ba5085af8f51769e60e8ecd5e99b55b2ced097cf2343e972ad7b',
|
||||
'org.jetbrains.kotlin:kotlin-stdlib:1.3.50:kotlin-stdlib-1.3.50.jar:e6f05746ee0366d0b52825a090fac474dcf44082c9083bbb205bd16976488d6c',
|
||||
'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.1.1:kotlinx-coroutines-core-1.1.1.jar:ac423f8a0aa4b4e74529696ff82c0171f81a8c8ab182a1965dff25e69c1f7844',
|
||||
|
||||
Reference in New Issue
Block a user