fixes according to updates

This commit is contained in:
2022-05-07 20:48:17 +06:00
parent 7551d7c2bb
commit a3ff08af27
24 changed files with 61 additions and 168 deletions
features
auth
client
src
commonMain
kotlin
dev
inmo
postssystem
server
src
jvmMain
common
server
build.gradle
src
jvmMain
kotlin
dev
inmo
postssystem
features
files
client
src
commonMain
kotlin
dev
inmo
postssystem
features
server
src
jvmMain
kotlin
dev
inmo
postssystem
features
roles
manager
server
src
jvmMain
kotlin
dev
inmo
postssystem
features
roles
server
status
server
src
jvmMain
kotlin
dev
inmo
postssystem
features
users
server
build.gradle
src
jvmMain
kotlin
dev
inmo
postssystem
gradle
mppJavaProject.gradle
publicators/simple/server/src/jvmMain/kotlin/dev/inmo/postssystem/publicators/simple/server
services/posts
client
src
commonMain
kotlin
dev
inmo
postssystem
jsMain
kotlin
dev
inmo
postssystem
services
jvmMain
kotlin
dev
inmo
postssystem
services
server
src
jvmMain
kotlin
dev
inmo
postssystem
targets/telegram/publication/server/src/jvmMain/kotlin/dev/inmo/postssystem/targets/telegram/publication/server

@ -5,11 +5,11 @@ import dev.inmo.postssystem.features.users.common.User
import dev.inmo.micro_utils.common.*
import dev.inmo.micro_utils.coroutines.launchSafelyWithoutExceptions
import io.ktor.client.HttpClientConfig
import io.ktor.client.features.cookies.*
import io.ktor.client.features.expectSuccess
import io.ktor.client.plugins.cookies.AcceptAllCookiesStorage
import io.ktor.client.plugins.cookies.HttpCookies
import io.ktor.client.plugins.expectSuccess
import io.ktor.client.request.*
import io.ktor.client.statement.HttpReceivePipeline
import io.ktor.client.statement.HttpResponse
import io.ktor.client.statement.*
import io.ktor.http.*
import kotlinx.coroutines.*
import kotlinx.coroutines.sync.Mutex
@ -25,10 +25,6 @@ fun HttpClientConfig<*>.installClientAuthenticator(
onUserRetrieved: suspend (User?) -> Unit,
onAuthKeyInvalidated: suspend () -> Unit
) {
// install(Logging) {
// logger = Logger.DEFAULT
// level = LogLevel.HEADERS
// }
install(HttpCookies) {
// Will keep an in-memory map with all the cookies from previous requests.
storage = AcceptAllCookiesStorage()
@ -98,13 +94,13 @@ fun HttpClientConfig<*>.installClientAuthenticator(
receivePipeline.intercept(HttpReceivePipeline.Before) {
if (
context.request.url.toString().startsWith(baseUrl)
&& context.response.status == HttpStatusCode.Unauthorized
it.request.url.toString().startsWith(baseUrl)
&& it.status == HttpStatusCode.Unauthorized
) {
authMutex.withLock { refreshToken() }
val newResponse = context.client ?.request<HttpResponse>{
takeFrom(context.request)
} ?: return@intercept
val newResponse = it.call.client.request {
takeFrom(it.request)
}
proceedWith(newResponse)
}
}

@ -7,12 +7,12 @@ import dev.inmo.postssystem.features.users.common.User
import dev.inmo.micro_utils.coroutines.safely
import dev.inmo.micro_utils.ktor.server.*
import dev.inmo.micro_utils.ktor.server.configurators.*
import io.ktor.application.*
import io.ktor.auth.*
import io.ktor.http.HttpStatusCode
import io.ktor.response.respond
import io.ktor.routing.*
import io.ktor.sessions.*
import io.ktor.server.application.call
import io.ktor.server.auth.*
import io.ktor.server.response.respond
import io.ktor.server.routing.*
import io.ktor.server.sessions.sessions
import kotlinx.serialization.builtins.nullable
data class AuthUserPrincipal(
@ -107,7 +107,7 @@ class AuthenticationRoutingConfigurator(
}
}
override fun Authentication.Configuration.invoke() {
override fun AuthenticationConfig.invoke() {
session<AuthToken> {
validate {
val result = authTokensService.getUserPrincipal(it)

@ -4,14 +4,14 @@ import dev.inmo.postssystem.features.auth.common.AuthToken
import dev.inmo.postssystem.features.common.common.Milliseconds
import dev.inmo.postssystem.features.auth.common.tokenSessionKey
import dev.inmo.micro_utils.ktor.server.configurators.ApplicationSessionsConfigurator
import io.ktor.sessions.*
import io.ktor.server.sessions.*
import java.util.concurrent.TimeUnit
class SessionAuthenticationConfigurator(
private val maxAge: Milliseconds
) : ApplicationSessionsConfigurator.Element {
private val maxAgeInSeconds = TimeUnit.MILLISECONDS.toSeconds(maxAge)
override fun Sessions.Configuration.invoke() {
override fun SessionsConfig.invoke() {
cookie<AuthToken>(tokenSessionKey) {
cookie.maxAgeInSeconds = maxAgeInSeconds
serializer = object : SessionSerializer<AuthToken> {

@ -17,7 +17,7 @@ kotlin {
}
jvmMain {
dependencies {
api libs.ktor.auth
api libs.ktor.server.auth
api libs.logback
}
}

@ -1,14 +1,13 @@
package dev.inmo.postssystem.features.common.server.sessions
import dev.inmo.micro_utils.ktor.server.configurators.KtorApplicationConfigurator
import io.ktor.application.Application
import io.ktor.auth.Authentication
import io.ktor.auth.authentication
import io.ktor.server.application.Application
import io.ktor.server.auth.*
class ApplicationAuthenticationConfigurator(
private val elements: List<Element>
) : KtorApplicationConfigurator {
fun interface Element { operator fun Authentication.Configuration.invoke() }
fun interface Element { operator fun AuthenticationConfig.invoke() }
override fun Application.configure() {
authentication {

@ -8,6 +8,7 @@ import dev.inmo.micro_utils.repos.ReadCRUDRepo
import dev.inmo.micro_utils.repos.ktor.client.crud.KtorReadStandardCrudRepo
import io.ktor.client.HttpClient
import io.ktor.client.request.post
import io.ktor.client.request.setBody
import io.ktor.client.statement.HttpResponse
import io.ktor.client.statement.readBytes
import kotlinx.serialization.BinaryFormat
@ -31,8 +32,8 @@ class ClientReadFilesStorage(
filesGetFilesPathPart
)
override suspend fun getBytes(id: FileId): ByteArray = client.post<HttpResponse>(fullFilesGetBytesPath) {
body = serialFormat.encodeToByteArray(FileId.serializer(), id)
override suspend fun getBytes(id: FileId): ByteArray = client.post(fullFilesGetBytesPath) {
setBody(serialFormat.encodeToByteArray(FileId.serializer(), id))
}.readBytes()
override suspend fun getFullFileInfo(

@ -6,10 +6,10 @@ import dev.inmo.micro_utils.ktor.server.*
import dev.inmo.micro_utils.ktor.server.configurators.ApplicationRoutingConfigurator
import dev.inmo.micro_utils.repos.ktor.server.crud.configureReadStandardCrudRepoRoutes
import dev.inmo.micro_utils.repos.ktor.server.crud.configureWriteStandardCrudRepoRoutes
import io.ktor.application.call
import io.ktor.auth.authenticate
import io.ktor.response.respondBytes
import io.ktor.routing.*
import io.ktor.server.application.call
import io.ktor.server.auth.authenticate
import io.ktor.server.response.respondBytes
import io.ktor.server.routing.*
import kotlinx.serialization.builtins.nullable
class FilesRoutingConfigurator(

@ -4,7 +4,7 @@ import dev.inmo.postssystem.features.roles.common.*
import dev.inmo.postssystem.features.roles.manager.common.GeneralRolesManagerRole
import dev.inmo.postssystem.features.roles.server.RolesChecker
import dev.inmo.postssystem.features.users.common.User
import io.ktor.application.ApplicationCall
import io.ktor.server.application.ApplicationCall
object RolesManagerRolesChecker : RolesChecker<Role> {
override val key: String

@ -2,7 +2,7 @@ package dev.inmo.postssystem.features.roles.server
import dev.inmo.postssystem.features.roles.common.*
import dev.inmo.postssystem.features.users.common.User
import io.ktor.application.ApplicationCall
import io.ktor.server.application.ApplicationCall
interface RolesChecker<T : Role> {
val key: String

@ -3,9 +3,8 @@ package dev.inmo.postssystem.features.roles.server
import dev.inmo.postssystem.features.roles.common.*
import dev.inmo.micro_utils.ktor.server.*
import dev.inmo.micro_utils.ktor.server.configurators.ApplicationRoutingConfigurator
import io.ktor.application.call
import io.ktor.auth.authenticate
import io.ktor.routing.*
import io.ktor.server.auth.authenticate
import io.ktor.server.routing.*
import kotlinx.serialization.KSerializer
import kotlinx.serialization.builtins.serializer

@ -6,18 +6,16 @@ import dev.inmo.postssystem.features.auth.server.tokens.AuthTokensService
import dev.inmo.postssystem.features.common.server.sessions.ApplicationAuthenticationConfigurator
import dev.inmo.postssystem.features.roles.common.Role
import dev.inmo.postssystem.features.roles.common.RolesStorage
import io.ktor.application.call
import io.ktor.auth.Authentication
import io.ktor.auth.session
import io.ktor.http.HttpStatusCode
import io.ktor.response.respond
import io.ktor.server.auth.*
import io.ktor.server.response.respond
class RolesAuthenticationConfigurator<T : Role>(
private val usersRolesStorage: RolesStorage<T>,
private val authTokensService: AuthTokensService,
private val rolesCheckers: List<RolesChecker<T>>
) : ApplicationAuthenticationConfigurator.Element {
override fun Authentication.Configuration.invoke() {
override fun AuthenticationConfig.invoke() {
rolesCheckers.forEach { checker ->
session<AuthToken>(checker.key) {
validate {

@ -3,8 +3,8 @@ package dev.inmo.postssystem.features.roles.server
import dev.inmo.postssystem.features.roles.common.*
import dev.inmo.micro_utils.ktor.server.*
import dev.inmo.micro_utils.ktor.server.configurators.ApplicationRoutingConfigurator
import io.ktor.auth.authenticate
import io.ktor.routing.*
import io.ktor.server.auth.authenticate
import io.ktor.server.routing.*
import kotlinx.serialization.KSerializer
import kotlinx.serialization.builtins.ListSerializer
import kotlinx.serialization.builtins.serializer

@ -3,11 +3,11 @@ package dev.inmo.postssystem.features.status.server
import dev.inmo.postssystem.features.status.common.statusAuthorisedPathPart
import dev.inmo.postssystem.features.status.common.statusRootPart
import dev.inmo.micro_utils.ktor.server.configurators.ApplicationRoutingConfigurator
import io.ktor.application.call
import io.ktor.auth.authenticate
import io.ktor.http.HttpStatusCode
import io.ktor.response.respond
import io.ktor.routing.*
import io.ktor.server.application.call
import io.ktor.server.auth.authenticate
import io.ktor.server.response.respond
import io.ktor.server.routing.*
object StatusRoutingConfigurator : ApplicationRoutingConfigurator.Element {
override fun Route.invoke() {

@ -15,7 +15,7 @@ kotlin {
}
jvmMain {
dependencies {
api libs.ktor.auth
api libs.ktor.server.auth
api libs.ktor.server.sessions
}
}

@ -4,9 +4,9 @@ import dev.inmo.micro_utils.ktor.server.UnifiedRouter
import dev.inmo.postssystem.features.users.common.*
import dev.inmo.micro_utils.ktor.server.configurators.ApplicationRoutingConfigurator
import dev.inmo.micro_utils.repos.ktor.server.crud.configureReadStandardCrudRepoRoutes
import io.ktor.auth.authenticate
import io.ktor.routing.Route
import io.ktor.routing.route
import io.ktor.server.auth.authenticate
import io.ktor.server.routing.Route
import io.ktor.server.routing.route
import kotlinx.serialization.builtins.nullable
class UsersStorageServerRoutesConfigurator(

@ -53,7 +53,7 @@ ktor-client-apache = { module = "io.ktor:ktor-client-apache", version.ref = "kto
ktor-client-auth = { module = "io.ktor:ktor-client-auth", version.ref = "ktor" }
ktor-client-logging = { module = "io.ktor:ktor-client-logging", version.ref = "ktor" }
ktor-http = { module = "io.ktor:ktor-http", version.ref = "ktor" }
ktor-auth = { module = "io.ktor:ktor-auth", version.ref = "ktor" }
ktor-server-auth = { module = "io.ktor:ktor-server-auth", version.ref = "ktor" }
ktor-server-netty = { module = "io.ktor:ktor-server-netty", version.ref = "ktor" }
ktor-server-sessions = { module = "io.ktor:ktor-server-sessions", version.ref = "ktor" }
ktor-websockets = { module = "io.ktor:ktor-websockets", version.ref = "ktor" }

@ -26,7 +26,6 @@ kotlin {
}
}
println(this::class)
allTargetsConfiguration()
}

@ -8,8 +8,8 @@ import dev.inmo.postssystem.features.publication.common.publicatorsRootPath
import dev.inmo.postssystem.features.publication.server.PublicationManager
import dev.inmo.postssystem.publicators.simple.common.simplePublicatorPublishPathPart
import dev.inmo.postssystem.publicators.simple.common.simplePublicatorRootPath
import io.ktor.application.call
import io.ktor.routing.*
import io.ktor.server.application.call
import io.ktor.server.routing.*
import kotlinx.serialization.builtins.serializer
class SimplePublicatorRoutingConfigurator(

@ -2,6 +2,7 @@ package dev.inmo.postssystem.services.posts.client
import dev.inmo.micro_utils.common.*
import dev.inmo.micro_utils.ktor.client.UnifiedRequester
import dev.inmo.micro_utils.ktor.client.tempUpload
import dev.inmo.micro_utils.ktor.common.buildStandardUrl
import dev.inmo.micro_utils.ktor.common.encodeHex
import dev.inmo.micro_utils.repos.ktor.common.crud.createRouting
@ -10,6 +11,7 @@ import dev.inmo.micro_utils.repos.ktor.common.one_to_many.removeRoute
import dev.inmo.postssystem.features.common.common.FileBasedInputProvider
import dev.inmo.postssystem.features.common.common.SimpleInputProvider
import dev.inmo.postssystem.features.content.common.*
import dev.inmo.postssystem.features.files.common.FileId
import dev.inmo.postssystem.features.posts.common.PostId
import dev.inmo.postssystem.features.posts.common.RegisteredPost
import dev.inmo.postssystem.services.posts.common.*
@ -61,7 +63,7 @@ class ClientWritePostsService(
provider.file
)
println(fileId)
it.copy(inputProvider = TempFileIdentifierInputProvider(fileId))
it.copy(inputProvider = TempFileIdentifierInputProvider(FileId(fileId.string)))
}
is TempFileIdentifierInputProvider -> it
else -> return@prepareContent null

@ -1,12 +0,0 @@
package dev.inmo.postssystem.services.posts.client
import dev.inmo.micro_utils.common.MPPFile
import dev.inmo.micro_utils.ktor.client.UnifiedRequester
import dev.inmo.postssystem.features.files.common.FileId
internal expect suspend fun UnifiedRequester.tempUpload(
fullTempUploadDraftPath: String,
file: MPPFile,
onUpload: (Long, Long) -> Unit = { _, _ -> }
): FileId

@ -1,49 +0,0 @@
package dev.inmo.postssystem.services.posts.client
import dev.inmo.micro_utils.common.MPPFile
import dev.inmo.micro_utils.ktor.client.UnifiedRequester
import dev.inmo.postssystem.features.files.common.FileId
import kotlinx.coroutines.*
import kotlinx.coroutines.GlobalScope.coroutineContext
import org.w3c.xhr.*
internal actual suspend fun UnifiedRequester.tempUpload(
fullTempUploadDraftPath: String,
file: MPPFile,
onUpload: (Long, Long) -> Unit
): FileId {
val formData = FormData()
val answer = CompletableDeferred<FileId>()
formData.append(
"data",
file
)
val request = XMLHttpRequest()
request.responseType = XMLHttpRequestResponseType.TEXT
request.upload.onprogress = {
onUpload(it.loaded.toLong(), it.total.toLong())
}
request.onload = {
if (request.status == 200.toShort()) {
answer.complete(FileId(request.responseText))
} else {
answer.completeExceptionally(Exception("Something went wrong"))
}
}
request.onerror = {
answer.completeExceptionally(Exception("Something went wrong"))
}
request.open("POST", fullTempUploadDraftPath, true)
request.send(formData)
currentCoroutineContext().job.invokeOnCompletion {
runCatching {
request.abort()
}
}
return answer.await()
}

@ -1,38 +0,0 @@
package dev.inmo.postssystem.services.posts.client
import dev.inmo.micro_utils.common.MPPFile
import dev.inmo.micro_utils.common.filename
import dev.inmo.micro_utils.ktor.client.UnifiedRequester
import dev.inmo.micro_utils.ktor.client.inputProvider
import dev.inmo.postssystem.features.common.common.mimeType
import dev.inmo.postssystem.features.files.common.FileId
import io.ktor.client.features.onUpload
import io.ktor.client.request.forms.formData
import io.ktor.client.request.forms.submitFormWithBinaryData
import io.ktor.http.Headers
import io.ktor.http.HttpHeaders
internal actual suspend fun UnifiedRequester.tempUpload(
fullTempUploadDraftPath: String,
file: MPPFile,
onUpload: (Long, Long) -> Unit
): FileId {
val inputProvider = file.inputProvider()
val fileId = client.submitFormWithBinaryData<String>(
fullTempUploadDraftPath,
formData = formData {
append(
"data",
inputProvider,
Headers.build {
append(HttpHeaders.ContentType, file.mimeType.raw)
append(HttpHeaders.ContentDisposition, "filename=\"${file.filename.string}\"")
}
)
}
) {
onUpload(onUpload)
}
return FileId(fileId)
}

@ -16,16 +16,15 @@ import dev.inmo.postssystem.features.content.common.*
import dev.inmo.postssystem.features.files.common.FileId
import dev.inmo.postssystem.features.posts.common.*
import dev.inmo.postssystem.services.posts.common.*
import io.ktor.application.ApplicationCall
import io.ktor.application.call
import io.ktor.auth.authenticate
import io.ktor.http.HttpStatusCode
import io.ktor.http.content.PartData
import io.ktor.http.content.streamProvider
import io.ktor.request.isMultipart
import io.ktor.request.receiveMultipart
import io.ktor.response.respond
import io.ktor.routing.*
import io.ktor.server.application.ApplicationCall
import io.ktor.server.application.call
import io.ktor.server.auth.authenticate
import io.ktor.server.request.receiveMultipart
import io.ktor.server.response.respond
import io.ktor.server.routing.*
import io.ktor.util.asStream
import io.ktor.util.pipeline.PipelineContext
import io.ktor.utils.io.core.use

@ -7,12 +7,11 @@ import dev.inmo.postssystem.features.publication.server.PublicationPost
import dev.inmo.postssystem.features.publication.server.PublicationTarget
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.extensions.utils.shortcuts.executeUnsafe
import dev.inmo.tgbotapi.requests.abstracts.MultipartFile
import dev.inmo.tgbotapi.requests.abstracts.asMultipartFile
import dev.inmo.tgbotapi.requests.send.SendTextMessage
import dev.inmo.tgbotapi.requests.send.media.*
import dev.inmo.tgbotapi.types.ChatId
import dev.inmo.tgbotapi.utils.StorageFile
import dev.inmo.tgbotapi.utils.StorageFileInfo
import io.ktor.utils.io.ByteReadChannel
import io.ktor.utils.io.core.readBytes
import kotlinx.coroutines.delay
@ -26,9 +25,9 @@ class PublicationTargetTelegram(
when (val content = it.content) {
is BinaryContent -> {
val storageFile by lazy {
StorageFile(StorageFileInfo(content.filename.name)) {
MultipartFile(content.filename.name) {
content.inputProvider()
}.asMultipartFile()
}
}
when (content.mimeType) {
is KnownMimeTypes.Image.Jpeg,