[space] Use ktor server instead of raw sockets for authorization

GitOrigin-RevId: 04afb40b9a03d60bdb3cb0e30ffc12c432c00fe6
This commit is contained in:
Nikolay Rykunov
2020-09-28 19:24:21 +00:00
committed by intellij-monorepo-bot
parent e5fd38f81e
commit 0bca421754
4 changed files with 126 additions and 43 deletions
+72
View File
@@ -0,0 +1,72 @@
<component name="libraryTable">
<library name="ktor-server-jetty" type="repository">
<properties maven-id="io.ktor:ktor-server-jetty:1.3.1">
<exclude>
<dependency maven-id="org.jetbrains.kotlinx:kotlinx-coroutines-core-common" />
<dependency maven-id="org.jetbrains.kotlinx:kotlinx-coroutines-core" />
<dependency maven-id="org.jetbrains.kotlinx:kotlinx-coroutines-jdk8" />
<dependency maven-id="org.slf4j:slf4j-api" />
<dependency maven-id="org.jetbrains.kotlin:kotlin-reflect" />
<dependency maven-id="org.jetbrains.kotlin:kotlin-stdlib-common" />
<dependency maven-id="org.jetbrains.kotlin:kotlin-stdlib-jdk7" />
<dependency maven-id="org.jetbrains.kotlin:kotlin-stdlib-jdk8" />
<dependency maven-id="org.jetbrains.kotlin:kotlin-stdlib" />
</exclude>
</properties>
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/io/ktor/ktor-server-jetty/1.3.1/ktor-server-jetty-1.3.1.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlinx/atomicfu/0.14.1/atomicfu-0.14.1.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/io/ktor/ktor-server-host-common/1.3.1/ktor-server-host-common-1.3.1.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/io/ktor/ktor-server-core/1.3.1/ktor-server-core-1.3.1.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/io/ktor/ktor-utils-jvm/1.3.1/ktor-utils-jvm-1.3.1.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/io/ktor/ktor-io-jvm/1.3.1/ktor-io-jvm-1.3.1.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/io/ktor/ktor-http-jvm/1.3.1/ktor-http-jvm-1.3.1.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/com/typesafe/config/1.3.1/config-1.3.1.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/io/ktor/ktor-http-cio-jvm/1.3.1/ktor-http-cio-jvm-1.3.1.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/io/ktor/ktor-network/1.3.1/ktor-network-1.3.1.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/io/ktor/ktor-server-servlet/1.3.1/ktor-server-servlet-1.3.1.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/jetty/jetty-server/9.4.24.v20191120/jetty-server-9.4.24.v20191120.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/javax/servlet/javax.servlet-api/3.1.0/javax.servlet-api-3.1.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/jetty/jetty-http/9.4.24.v20191120/jetty-http-9.4.24.v20191120.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/jetty/jetty-io/9.4.24.v20191120/jetty-io-9.4.24.v20191120.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/jetty/jetty-servlets/9.4.24.v20191120/jetty-servlets-9.4.24.v20191120.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/jetty/jetty-continuation/9.4.24.v20191120/jetty-continuation-9.4.24.v20191120.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/jetty/jetty-util/9.4.24.v20191120/jetty-util-9.4.24.v20191120.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/jetty/jetty-alpn-server/9.4.24.v20191120/jetty-alpn-server-9.4.24.v20191120.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/jetty/jetty-alpn-openjdk8-server/9.4.24.v20191120/jetty-alpn-openjdk8-server-9.4.24.v20191120.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/jetty/jetty-alpn-java-server/9.4.24.v20191120/jetty-alpn-java-server-9.4.24.v20191120.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/jetty/alpn/alpn-api/1.1.3.v20160715/alpn-api-1.1.3.v20160715.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/jetty/http2/http2-server/9.4.24.v20191120/http2-server-9.4.24.v20191120.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/jetty/http2/http2-common/9.4.24.v20191120/http2-common-9.4.24.v20191120.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/jetty/http2/http2-hpack/9.4.24.v20191120/http2-hpack-9.4.24.v20191120.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/io/ktor/ktor-server-jetty/1.3.1/ktor-server-jetty-1.3.1-sources.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlinx/atomicfu/0.14.1/atomicfu-0.14.1-sources.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/io/ktor/ktor-server-host-common/1.3.1/ktor-server-host-common-1.3.1-sources.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/io/ktor/ktor-server-core/1.3.1/ktor-server-core-1.3.1-sources.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/io/ktor/ktor-utils-jvm/1.3.1/ktor-utils-jvm-1.3.1-sources.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/io/ktor/ktor-io-jvm/1.3.1/ktor-io-jvm-1.3.1-sources.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/io/ktor/ktor-http-jvm/1.3.1/ktor-http-jvm-1.3.1-sources.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/com/typesafe/config/1.3.1/config-1.3.1-sources.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/io/ktor/ktor-http-cio-jvm/1.3.1/ktor-http-cio-jvm-1.3.1-sources.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/io/ktor/ktor-network/1.3.1/ktor-network-1.3.1-sources.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/io/ktor/ktor-server-servlet/1.3.1/ktor-server-servlet-1.3.1-sources.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/jetty/jetty-server/9.4.24.v20191120/jetty-server-9.4.24.v20191120-sources.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/javax/servlet/javax.servlet-api/3.1.0/javax.servlet-api-3.1.0-sources.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/jetty/jetty-http/9.4.24.v20191120/jetty-http-9.4.24.v20191120-sources.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/jetty/jetty-io/9.4.24.v20191120/jetty-io-9.4.24.v20191120-sources.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/jetty/jetty-servlets/9.4.24.v20191120/jetty-servlets-9.4.24.v20191120-sources.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/jetty/jetty-continuation/9.4.24.v20191120/jetty-continuation-9.4.24.v20191120-sources.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/jetty/jetty-util/9.4.24.v20191120/jetty-util-9.4.24.v20191120-sources.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/jetty/jetty-alpn-server/9.4.24.v20191120/jetty-alpn-server-9.4.24.v20191120-sources.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/jetty/jetty-alpn-openjdk8-server/9.4.24.v20191120/jetty-alpn-openjdk8-server-9.4.24.v20191120-sources.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/jetty/jetty-alpn-java-server/9.4.24.v20191120/jetty-alpn-java-server-9.4.24.v20191120-sources.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/jetty/alpn/alpn-api/1.1.3.v20160715/alpn-api-1.1.3.v20160715-sources.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/jetty/http2/http2-server/9.4.24.v20191120/http2-server-9.4.24.v20191120-sources.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/jetty/http2/http2-common/9.4.24.v20191120/http2-common-9.4.24.v20191120-sources.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/jetty/http2/http2-hpack/9.4.24.v20191120/http2-hpack-9.4.24.v20191120-sources.jar!/" />
</SOURCES>
</library>
</component>
@@ -440,6 +440,11 @@ class CommunityLibraryLicenses {
license: "Apache 2.0",
licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0",
url: "https://github.com/ktorio/ktor"),
new LibraryLicense(name: "ktor-server-jetty",
libraryName: "ktor-server-jetty",
license: "Apache 2.0",
licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0",
url: "https://github.com/ktorio/ktor"),
new LibraryLicense(name: "ktor-websockets",
libraryName: "ktor-websockets",
license: "Apache 2.0",
+1
View File
@@ -107,6 +107,7 @@
</library>
</orderEntry>
<orderEntry type="library" name="space-idea-sdk" level="project" />
<orderEntry type="library" name="ktor-server-jetty" level="project" />
<orderEntry type="library" scope="RUNTIME" name="jackson" level="project" />
<orderEntry type="library" scope="RUNTIME" name="jackson-databind" level="project" />
<orderEntry type="library" scope="RUNTIME" name="jackson-datatype-joda" level="project" />
@@ -1,14 +1,19 @@
package com.intellij.space.auth
import com.intellij.openapi.application.ApplicationManager
import com.intellij.util.concurrency.AppExecutorUtil
import io.ktor.network.selector.ActorSelectorManager
import io.ktor.network.sockets.ServerSocket
import io.ktor.network.sockets.aSocket
import io.ktor.network.sockets.openReadChannel
import io.ktor.network.sockets.openWriteChannel
import io.ktor.utils.io.readUTF8Line
import io.ktor.utils.io.writeStringUtf8
import kotlinx.coroutines.*
import io.ktor.application.call
import io.ktor.http.ContentType
import io.ktor.request.uri
import io.ktor.response.respondText
import io.ktor.routing.get
import io.ktor.routing.routing
import io.ktor.server.engine.embeddedServer
import io.ktor.server.jetty.Jetty
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.Deferred
import kotlinx.coroutines.Runnable
import kotlinx.coroutines.asCoroutineDispatcher
import libraries.coroutines.extra.Lifetime
import libraries.coroutines.extra.launch
import java.io.IOException
@@ -16,51 +21,51 @@ import java.io.IOException
private val ioDispatcher = AppExecutorUtil.getAppExecutorService().asCoroutineDispatcher()
internal suspend fun startRedirectHandling(lifetime: Lifetime, ports: Collection<Int>): SpaceRedirectHandlingInfo? {
val redirectUrl = CompletableDeferred<String>()
val freePort = occupyAvailablePort(lifetime, ports) { serverSocket ->
val socket = serverSocket.accept()
launch(lifetime, ioDispatcher) {
val response = "<script>close()</script>"
val output = socket.openWriteChannel(autoFlush = true)
output.writeStringUtf8(
"""
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: ${response.length}
$response
""".trimIndent()
)
}
val input = socket.openReadChannel()
val line = input.readUTF8Line()!!.substringAfter("/").substringBefore(" ")
redirectUrl.complete(line)
} ?: return null
return SpaceRedirectHandlingInfo(freePort, redirectUrl)
}
private suspend fun occupyAvailablePort(lifetime: Lifetime, ports: Collection<Int>, withFreePort: suspend (ServerSocket) -> Unit): Int? {
val reservedPort = CompletableDeferred<Int?>()
val info = CompletableDeferred<SpaceRedirectHandlingInfo?>()
launch(lifetime, ioDispatcher) {
for (port in ports.distinct().shuffled()) {
try {
aSocket(ActorSelectorManager(ioDispatcher)).tcp().bind(port = port).use { socket ->
reservedPort.complete(port)
withFreePort(socket)
}
val redirectUrl = startAuthServerAsync(lifetime, port)
info.complete(SpaceRedirectHandlingInfo(port, redirectUrl))
break
}
catch (e: IOException) {
if (reservedPort.isCompleted) {
throw e
}
// check next port
}
}
reservedPort.complete(null)
info.complete(null)
}
return reservedPort.await()
return info.await()
}
private fun startAuthServerAsync(lifetime: Lifetime, port: Int): Deferred<String> {
val redirectUrl = CompletableDeferred<String>()
val server = embeddedServer(Jetty, port = port, host = "localhost") {
routing {
get("/auth") {
call.respondText(
"<html><body><script>close()</script></body></html>",
contentType = ContentType.Text.Html
)
redirectUrl.complete(call.request.uri)
}
}
}
server.start(wait = false)
fun stopServer() {
ApplicationManager.getApplication().executeOnPooledThread(Runnable {
server.stop(1000, 1000)
})
}
lifetime.addOrCallImmediately {
stopServer()
}
redirectUrl.invokeOnCompletion {
stopServer()
}
return redirectUrl
}
internal data class SpaceRedirectHandlingInfo(val port: Int, val redirectUrl: Deferred<String>)