This commit is contained in:
cheykrym 2025-07-14 19:58:36 +03:00
parent 90d0b1d5c7
commit 5294dba0d4
8 changed files with 248 additions and 21 deletions

4
.gitignore vendored
View File

@ -2,6 +2,7 @@ target/
!.mvn/wrapper/maven-wrapper.jar !.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/ !**/src/main/**/target/
!**/src/test/**/target/ !**/src/test/**/target/
resources/cert/
### IntelliJ IDEA ### ### IntelliJ IDEA ###
.idea/modules.xml .idea/modules.xml
@ -44,4 +45,5 @@ build/
.DS_Store .DS_Store
### Scala ### ### Scala ###
.bsp/ .bsp/
/src/main/resources/cert/

View File

@ -0,0 +1,29 @@
-----BEGIN CERTIFICATE-----
MIIFBzCCAu+gAwIBAgIUKyGocacasiFTydz+5BlbnHBbkDUwDQYJKoZIhvcNAQEL
BQAwEzERMA8GA1UEAwwITXlSb290Q0EwHhcNMjUwNzA5MjMxODIyWhcNMzUwNzA3
MjMxODIyWjATMREwDwYDVQQDDAhNeVJvb3RDQTCCAiIwDQYJKoZIhvcNAQEBBQAD
ggIPADCCAgoCggIBANTSCG9S38oiDBtRKUOn2fspTPbvhnCbthumERqJ3sDcVM9E
u+G7/7dBs2ezJgq+A4ub/Mlb03O+pUAnn29I5UGxApv6MCtorkm10J3U2m8tILV6
LrHtBLX9C/P5u911dyYeXE4st2l9JzlvBQMW9dujPvpF225rUWHy+Bb0CpGK65st
64itPIeTZdZ+ZNobrLrzj7wUrzY/7OoCJ5/lOJsEOA3OlJ5ymdJAJOqsKfr7tIWe
1V1nWmCictYsQ8CyRnFqwOf54uXYbOmu+yN0EOTqGst8E9BN4ZZUE9mvByURJGGB
mqcp7G1tvlUrs3iGixb1jjDpnkw77BYEa+/UkYRf+swnn08zAq7FlqJfaNxOLOha
cxBksZHHC2gYzd77alrfYGo53AnwuzHDvzkdhJ5NfDZpjovKd36jpvI8ZtV2b6Rm
qWPVMOAe+jGVjvFc8JqmXIUBSsUX0u0vJcdnzeY7jeSLggpSIht1SPBUic88S9ti
2U/lF5d3PLHd+pUjOhOsbL/bZVo2YRvy22nKKLRc+QchF+b6ImeZcx+85TEG55Gv
+A54t3BzBOTC7s28lsVl17+2Tb0FGSlStgXfoHs2mz1TLrKUaqqSyqdoIuSAZXSH
MK1L2U1QwWojHa9Lp5B9DWIfTa+tLQFV7/T3lzDhCuxcm+XZJO7iqHpybKb9AgMB
AAGjUzBRMB0GA1UdDgQWBBRfj+XIdi262e1rjrHAY/2mz/jGcjAfBgNVHSMEGDAW
gBRfj+XIdi262e1rjrHAY/2mz/jGcjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3
DQEBCwUAA4ICAQBcL05HJSDV8xx88qUs3kO6wiiOxqTii3cKFInUFM/fDgJy8eku
9rXmT1QH/n2MOYpYm6GBtspg5wdj5y4/DFFUsWaaU3JUFn2XYVujD1I9Re2PuQ7l
4KlFmy3Ng8+zKioUWchs+dv2EWIc82MPoEJRUoEZEc5HKfLMuvS6ikGU9Z9q3wUz
p3EvNMGtPGxZdxvm4lBODS3N7fQaCGJYjBD/gGPAAc1sCvZdaYYULa8kzmwYiI24
olh0FwDvHn6798humlNIDlgSrhAKnR4zXQJPcezmvWR+W9hVV4roHDfhsjNK2Yfi
tH3twTSZ5QdRFavEBPqf+5v8pr37hBUUq8pDW4ooJK3XLIBhRejhLOIsiAw6cw0t
N3QQPwauvyoaGfk72LYoJj/kiW1XfzkH+6oRNUY4CP9s4cyRU80Ef+Sal0SyvJxJ
ZjXnFDEkzz3qZ9DySAn0StMQj2zAcm8N0xok7eKk2ElXPBcTrrxLoVIcxBtMpjsJ
2xxJOZ+q38Sf6RR045oo6zjUdHG3B22JecSdihkTYvXWhSlQm2thoV39jBCuMngU
lotSmBITsFq80PEegsPa/2KjONU5pI7BM61A8uPqPLbTPLl5MJO3gwAQfNnMzUrB
hKrXILtRi/DYOVUxjJfSUFc4RM+A++zBzhFGkuBNa5IG6W678Ndm6r+zTw==
-----END CERTIFICATE-----

View File

@ -0,0 +1,28 @@
-----BEGIN CERTIFICATE-----
MIIEvzCCAqcCFEaIJVwzuQMoeUJ2onT2HKNV82nUMA0GCSqGSIb3DQEBCwUAMBMx
ETAPBgNVBAMMCE15Um9vdENBMB4XDTI1MDcwOTIzMTgzNVoXDTI2MDcwOTIzMTgz
NVowJTEjMCEGA1UEAwwaeW9iYmxlLWF1dGgtc2VydmljZS1jbGllbnQwggIiMA0G
CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC3jG3LT1ni+loLBGpXPMobZFt/yLX1
/qd/wXQMpmRckpcHmsqOHZAs2Fw2ybA2PoUuTxriKIChdvrfDLlHHmIDwI2S861p
Pk7J7Phzr+4GN0ByGIODtA/mOkpHS0aE75siFNbfC9KNOsmRxNDcwrjzbv5ynnrX
WYl6J7NG6YcYaPHRnJYJV7DJFtQGKD+0z0fK4QdX3elxYmiDlPFj7G7o5pMo5vhm
MdNBSb85KZubQGYWXn7ggg+NdHK25aksWhWXnyttNv/55HqQdt7wsDeGfzlGM2gq
xvFobkaWJ8jE5MPeSgfDLoy2wmhqar4egtzyBs/8soE7sdgX6/796CHKQZNw5yJF
wwSQx7OBZW++5B5eQblKMEWsCa7TS7kXx1VggqBfYheSVjjBXvYjTDwfIdsZnwzl
HEF2dEWden3b1/AI0oFhIwWY/x7ndOfEERQ50BB5or1+VvkUxD1N4ibr7NMggDnr
nUSxT+enlHqm7yxqcQDi0ZD9Yxs9ghhDAT4RXr97Wi/q1sIbfPlXZjKnpzwBMxBf
G6mZJ/LzGO57pjuCQCpz1BERl4jp/H4lDHZqtBCBnhueYBf+kfGKH5exGv4fNnV2
WFHpQ9cJVkl3SsxrkrfYt3czyqsRZqJAOWxmoOw1g+hpiXa1XycK0ys8Y+cb8vVU
+eoj5RvDgpzjQQIDAQABMA0GCSqGSIb3DQEBCwUAA4ICAQCoxysC2SWJ407g/O0J
b4Z6sbhyXcrc1jLHnnAT9y+4V0ih4XWAr4xYuKKTPJXZNPAaLq39xet6zDtDTHEF
jChBxtRpwxZgmJgSfK34FSJvYjAIiiBwwYnsCHCm5xI7z7lRdLSlCmgrmNWIH0dX
KjpyGOYZEiT24xZZHwLzWxaaog7PFyEMCs0c9NVhM5STjLFH7h7jiTO146c5xtAW
eue4/wtRUOKwXan5CwnERhqgEouxDGswPVXKQityjrXtHPYN+X43rXHnRPbCpgsi
o5iM/qjCDRdMsP8GE9mWbMCXsZc6eO/2Xhxn2KCT86xYfsgZ9k8ZXDzjj8XkfJiE
MUm/dlEsOCDStpWCcUiz2r6upMGk04dfy4I2Ck+juoGzuCZNFZcb8YeLt0T58Miq
BgLZdqc73C8Iy/qdm+I7DlwkoQ/myt+V9O1+rUvrhqW1ymHyAsBevEis01NzksIQ
inqg4p6FohjdPKcvlmkvwsiojAiC+1C1Rhhj6F3oUpHP1/VmwTHsHZGla30FZanm
5556hep67yZ4GIn1G4ETLCpIn+npIx3aQ6cix93kdK3DaaX8fJJbnAbWaZ7smNh/
jqMiKBetV1lMRCbH3yZ+4rk0yZu12TrX4Hx8DZ9W3UdhOdFlZFBnXiPwYYwPapkn
9dTT3Ae76gUZHZ0tABce0W0owA==
-----END CERTIFICATE-----

View File

@ -0,0 +1,51 @@
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----

View File

@ -0,0 +1,28 @@
-----BEGIN CERTIFICATE-----
MIIEuDCCAqACFEaIJVwzuQMoeUJ2onT2HKNV82nTMA0GCSqGSIb3DQEBCwUAMBMx
ETAPBgNVBAMMCE15Um9vdENBMB4XDTI1MDcwOTIzMTgzNFoXDTI2MDcwOTIzMTgz
NFowHjEcMBoGA1UEAwwTeW9iYmxlLWF1dGgtc2VydmljZTCCAiIwDQYJKoZIhvcN
AQEBBQADggIPADCCAgoCggIBAMo1MrgxF6s9QzBivJNTO1f1goz10pCyngSUBj6N
dDhcbEkGsEZfJ/B36QPlRLrcm7VvDqquX+kipKTpDQOAFgFkn/2t24Kuo6RqL+4R
Cu+DJBy9DYVFBFPM9jiQxUBNEEfwLZHP/EcR8UXJb/DY5nsjuIH6DZ0OH+aKCcAW
4T2ls8IxrWtrEEjmhPFmMlichD5/t/XnC8qUbaXijjH9aj1d0+VoRECUp3WKlkNS
wTfrbFtzxdusivnYCAh2o+Adg4oFBbSvF+rxBg3bVAQnMJ+5vK7AhofMYcOtn7/f
gkg4Q31UNyfD9B4MkiFTkYeKKEQiqIIWCnSBAWoeCGikWKbEL2Y+tENrWe6tyD5H
amYVg+10ga8aBMchE39YzbxpnssC9wQ3ssfo4ShC/GQtERaci/q0kIdKOpYxHYxV
s0mKNS/CSxN+OsZO07mxqXMbQq+uu56nxgAiD7IbVaur0sUPmNDmpButOFjrnhzH
fN19dPKUCwo0QlKejL8/6FJzddTB1rmgB9obdioWLfwuDjWqkauTMjoFNbqVAvFE
Vi6oXf0JZsuy1NVndAhzBjV5eNKK/J8D1nSt26DNRbZnilPBcBA+6TinXsFv1WMh
fNuilwbP4mRwOtTWeUkffTO/ByzucMtJfFOKFhMlg/+TaYlUvfpG1GZt4CEaxHWF
AccNAgMBAAEwDQYJKoZIhvcNAQELBQADggIBAJ435s3d5XTAohnZMsRwlMg9eCfd
3Q8rZj4LNQLj3zHRYnfP+f6w48u/eU0OQPXgE6yT9w2g1j42Lyv4ay2cnZUDvNln
vtUkJfbD9WqP5d+wumGlK29XJtXt57NiZJSn5I9Reml0uGpVAQHoRlAvquWQaVBD
RV9tUWMtw65NZ2cZSFg4f+Yg+dIumTGrIhOJw1ixQP4F/sP/aMUxoHdS4mZvrxNV
mviit+PR3pK/ehNzO3c8U1+o9PKcyCyRAfLdvLmrXhlh1ujcf0lO5kI1Uvqes0O9
O6t5LqBvtGWp+BF+v2yshLLrsNWeudlu6H5NEugfsUWJdUoTauyG04/gZhAaiINs
IQmDzxHqVWxOa9N43cfYUgllaTDUvq+T06KHMVAERU2BaPJcxiFccmHAWWH3Nmx/
IdGpel+3g1nWOLkX7EkVvz5vO2wUJliG6zqS743wSUUdhvRFAHsvQmjT4p7Qxk1l
WG3uPGQS71LN3NZNq7WQUsMB1ucGleotNsrjXy2mhBdeBMOodBjXpxDzZLVJ+Pfg
2Sf+XbuD4qi6kXMKBD4jLY4e4FU8Fnz2AR9MsDFXFTegbWyI0d42/w91iKfReKCF
RFY50QCHhpbykF4tHSaMKJelsTjiFAN/XOU2xNUnMMkTzfeddrsLdG0F/j8J1l/f
AhZZZuw0yfKKexdv
-----END CERTIFICATE-----

View File

@ -0,0 +1,51 @@
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----

View File

@ -1,34 +1,54 @@
package org.yobble.chat_private_service package org.yobble.chat_private_service
import java.security.KeyStore
import java.security.cert.CertificateFactory
import java.io.InputStream
import javax.net.ssl.TrustManagerFactory
import cats.effect.* import cats.effect.*
import io.circe.generic.auto.* import com.comcast.ip4s.{host, Port}
import org.http4s.* import org.http4s.ember.server.EmberServerBuilder
import org.http4s.circe.* import fs2.io.net.tls.TLSContext
import org.http4s.dsl.io.* import org.yobble.chat_private_service.config.AppConfig
import org.http4s.ember.server.* import org.yobble.chat_private_service.api.route.Routes
import org.yobble.module.middleware.GlobalErrorHandler
import org.http4s.implicits.* import org.http4s.implicits.*
import org.http4s.server.Router import org.http4s.server.Router
import cats.implicits.toSemigroupKOps def loadTrustManager(caCertPath: Path): IO[TrustManagerFactory] = IO {
import com.comcast.ip4s.{Port, host} val certFactory = CertificateFactory.getInstance("X.509")
import org.http4s.circe.CirceEntityCodec.* val trustStore = KeyStore.getInstance(KeyStore.getDefaultType)
import org.yobble.chat_private_service.api.route.Routes trustStore.load(null, null) // создаём пустой truststore
import org.yobble.chat_private_service.config.AppConfig
import org.yobble.module.middleware.GlobalErrorHandler
object Main extends IOApp { val caCertStream: InputStream = Files.newInputStream(caCertPath)
override def run(args: List[String]): IO[ExitCode] = val caCert = certFactory.generateCertificate(caCertStream)
AppModule.create.flatMap { routes => // создаём routes тут trustStore.setCertificateEntry("ca-cert", caCert)
val tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm)
tmf.init(trustStore)
tmf
}
override def run(args: List[String]): IO[ExitCode] =
AppModule.create.flatMap { routes =>
val tlsContextResource: Resource[IO, TLSContext[IO]] =
Resource.eval(loadTrustManager(AppConfig.CA_CERT)).flatMap { tmf =>
TLSContext.Builder.forAsync[IO]
.fromKeyAndCertFileWithTrustManager(
cert = AppConfig.TLS_CERT,
key = AppConfig.TLS_KEY,
trustManager = tmf
)
}
tlsContextResource.flatMap { tlsContext =>
EmberServerBuilder.default[IO] EmberServerBuilder.default[IO]
.withHost(host"0.0.0.0") .withHost(host"0.0.0.0")
.withPort(Port.fromInt(AppConfig.PORT).get) .withPort(Port.fromInt(AppConfig.PORT).get)
.withHttpApp(GlobalErrorHandler.withGlobalErrorHandler(routes.all.orNotFound)) .withHttpApp(GlobalErrorHandler.withGlobalErrorHandler(routes.all.orNotFound))
// .withTLS() .withTLS(tlsContext)
.withHttp2 .withHttp2
.build .build
}.use(_ => // внутри use }.use(_ =>
IO.println(s"Server running at http://0.0.0.0:${AppConfig.PORT}") *> IO.println(s"🚀 Server running with mTLS at https://0.0.0.0:${AppConfig.PORT}") *> IO.never
IO.println(s"Swagger UI available at http://0.0.0.0:${AppConfig.PORT}/docs") *>
IO.never
).as(ExitCode.Success) ).as(ExitCode.Success)
} }

View File

@ -1,7 +1,25 @@
package org.yobble.chat_private_service.config package org.yobble.chat_private_service.config
import java.nio.file.{Files, Path}
import java.nio.file.StandardCopyOption.REPLACE_EXISTING
object AppConfig { object AppConfig {
private def copyResourceToTempFile(resourcePath: String): Path = {
val inputStream = Option(getClass.getClassLoader.getResourceAsStream(resourcePath))
.getOrElse(throw new RuntimeException(s"Resource not found: $resourcePath"))
val tempFile = Files.createTempFile("cert-", resourcePath.split("/").last)
Files.copy(inputStream, tempFile, REPLACE_EXISTING)
tempFile
}
val CA_CERT: Path = copyResourceToTempFile("cert/ca.crt")
val TLS_CERT: Path = copyResourceToTempFile("cert/service.crt")
val TLS_KEY: Path = copyResourceToTempFile("cert/service.key")
val TLS_CLIENT_CERT: Path = copyResourceToTempFile("cert/client.crt")
val TLS_CLIENT_KEY: Path = copyResourceToTempFile("cert/client.key")
val HOST = "0.0.0.0" val HOST = "0.0.0.0"
val PORT = 5205 val PORT = 5205