start migration onto ktor-based serialization of data
This commit is contained in:
features
auth
server
src
jvmMain
kotlin
dev
inmo
postssystem
features
auth
content
common
src
commonMain
kotlin
dev
inmo
postssystem
features
content
common
files
client
src
commonMain
kotlin
dev
inmo
postssystem
features
files
server
src
jvmMain
kotlin
dev
inmo
postssystem
features
files
roles
client
src
commonMain
kotlin
dev
inmo
postssystem
common
src
commonMain
kotlin
dev
inmo
postssystem
features
roles
common
manager
server
src
jvmMain
kotlin
dev
inmo
postssystem
features
roles
server
src
jvmMain
kotlin
dev
inmo
postssystem
users
client
src
commonMain
kotlin
dev
inmo
postssystem
features
users
server
src
jvmMain
kotlin
dev
inmo
postssystem
features
users
publicators/simple/client/src/commonMain/kotlin/dev/inmo/postssystem/publicators/simple/client
server/src/main/java/dev/inmo/postssystem/server
services/posts
client
src
commonMain
kotlin
dev
inmo
postssystem
services
server
src
jvmMain
kotlin
dev
inmo
postssystem
services
posts
@ -10,6 +10,7 @@ import dev.inmo.micro_utils.ktor.server.configurators.*
|
|||||||
import io.ktor.http.HttpStatusCode
|
import io.ktor.http.HttpStatusCode
|
||||||
import io.ktor.server.application.call
|
import io.ktor.server.application.call
|
||||||
import io.ktor.server.auth.*
|
import io.ktor.server.auth.*
|
||||||
|
import io.ktor.server.request.receive
|
||||||
import io.ktor.server.response.respond
|
import io.ktor.server.response.respond
|
||||||
import io.ktor.server.routing.*
|
import io.ktor.server.routing.*
|
||||||
import io.ktor.server.sessions.sessions
|
import io.ktor.server.sessions.sessions
|
||||||
@ -24,11 +25,9 @@ fun User.principal() = AuthUserPrincipal(this)
|
|||||||
|
|
||||||
class AuthenticationRoutingConfigurator(
|
class AuthenticationRoutingConfigurator(
|
||||||
private val authFeature: AuthFeature,
|
private val authFeature: AuthFeature,
|
||||||
private val authTokensService: AuthTokensService,
|
private val authTokensService: AuthTokensService
|
||||||
private val unifiedRouter: UnifiedRouter
|
|
||||||
) : ApplicationRoutingConfigurator.Element, ApplicationAuthenticationConfigurator.Element {
|
) : ApplicationRoutingConfigurator.Element, ApplicationAuthenticationConfigurator.Element {
|
||||||
override fun Route.invoke() {
|
override fun Route.invoke() {
|
||||||
unifiedRouter.apply {
|
|
||||||
route(authRootPathPart) {
|
route(authRootPathPart) {
|
||||||
post(authAuthPathPart) {
|
post(authAuthPathPart) {
|
||||||
safely(
|
safely(
|
||||||
@ -41,7 +40,7 @@ class AuthenticationRoutingConfigurator(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
val creds = uniload(AuthCreds.serializer())
|
val creds = call.receive<AuthCreds>()
|
||||||
|
|
||||||
val tokenInfo = authFeature.auth(creds)
|
val tokenInfo = authFeature.auth(creds)
|
||||||
|
|
||||||
@ -51,10 +50,7 @@ class AuthenticationRoutingConfigurator(
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
call.sessions.set(tokenSessionKey, tokenInfo.token)
|
call.sessions.set(tokenSessionKey, tokenInfo.token)
|
||||||
unianswer(
|
call.respond(tokenInfo)
|
||||||
AuthTokenInfo.serializer().nullable,
|
|
||||||
tokenInfo
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -68,7 +64,7 @@ class AuthenticationRoutingConfigurator(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
val refreshToken = uniload(RefreshToken.serializer())
|
val refreshToken = call.receive<RefreshToken>()
|
||||||
|
|
||||||
val tokenInfo = authFeature.refresh(refreshToken)
|
val tokenInfo = authFeature.refresh(refreshToken)
|
||||||
|
|
||||||
@ -78,10 +74,7 @@ class AuthenticationRoutingConfigurator(
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
call.sessions.set(tokenSessionKey, tokenInfo.token)
|
call.sessions.set(tokenSessionKey, tokenInfo.token)
|
||||||
unianswer(
|
call.respond(tokenInfo)
|
||||||
AuthTokenInfo.serializer().nullable,
|
|
||||||
tokenInfo
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -95,13 +88,9 @@ class AuthenticationRoutingConfigurator(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
unianswer(
|
call.respond(
|
||||||
User.serializer().nullable,
|
authFeature.getMe(call.receive()) ?: HttpStatusCode.NoContent
|
||||||
authFeature.getMe(
|
|
||||||
uniload(AuthToken.serializer())
|
|
||||||
)
|
)
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package dev.inmo.postssystem.features.content.common
|
package dev.inmo.postssystem.features.content.common
|
||||||
|
|
||||||
import dev.inmo.micro_utils.common.FileName
|
import dev.inmo.micro_utils.common.*
|
||||||
import dev.inmo.micro_utils.common.MPPFile
|
|
||||||
import dev.inmo.micro_utils.mime_types.MimeType
|
import dev.inmo.micro_utils.mime_types.MimeType
|
||||||
import dev.inmo.postssystem.features.common.common.SimpleInputProvider
|
import dev.inmo.postssystem.features.common.common.SimpleInputProvider
|
||||||
import kotlinx.serialization.PolymorphicSerializer
|
import kotlinx.serialization.PolymorphicSerializer
|
||||||
@ -30,6 +29,18 @@ data class BinaryContent(
|
|||||||
) : Content
|
) : Content
|
||||||
|
|
||||||
val ContentSerializer = PolymorphicSerializer(Content::class)
|
val ContentSerializer = PolymorphicSerializer(Content::class)
|
||||||
|
@Serializable
|
||||||
|
data class ContentWrapper(
|
||||||
|
val content: Content
|
||||||
|
)
|
||||||
|
@Serializable
|
||||||
|
data class ContentsWrapper(
|
||||||
|
val content: List<Content>
|
||||||
|
)
|
||||||
|
@Serializable
|
||||||
|
data class ContentsEithersWrapper(
|
||||||
|
val content: List<Either<ContentId, Content>>
|
||||||
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Content which is already registered in database. Using its [id] you can retrieve all known
|
* Content which is already registered in database. Using its [id] you can retrieve all known
|
||||||
|
@ -25,7 +25,6 @@ class ClientReadFilesStorage(
|
|||||||
MetaFileInfoStorageWrapper.serializer().nullable,
|
MetaFileInfoStorageWrapper.serializer().nullable,
|
||||||
FileId.serializer()
|
FileId.serializer()
|
||||||
) {
|
) {
|
||||||
private val unifiedRequester = UnifiedRequester(client, serialFormat)
|
|
||||||
private val fullFilesPath = buildStandardUrl(baseUrl, filesRootPathPart)
|
private val fullFilesPath = buildStandardUrl(baseUrl, filesRootPathPart)
|
||||||
private val fullFilesGetBytesPath = buildStandardUrl(
|
private val fullFilesGetBytesPath = buildStandardUrl(
|
||||||
fullFilesPath,
|
fullFilesPath,
|
||||||
|
@ -4,10 +4,13 @@ import dev.inmo.postssystem.features.files.common.*
|
|||||||
import dev.inmo.postssystem.features.files.common.storage.*
|
import dev.inmo.postssystem.features.files.common.storage.*
|
||||||
import dev.inmo.micro_utils.ktor.server.*
|
import dev.inmo.micro_utils.ktor.server.*
|
||||||
import dev.inmo.micro_utils.ktor.server.configurators.ApplicationRoutingConfigurator
|
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.*
|
||||||
import dev.inmo.micro_utils.repos.ktor.server.crud.configureWriteStandardCrudRepoRoutes
|
import io.ktor.http.HttpStatusCode
|
||||||
|
import io.ktor.http.decodeURLQueryComponent
|
||||||
import io.ktor.server.application.call
|
import io.ktor.server.application.call
|
||||||
import io.ktor.server.auth.authenticate
|
import io.ktor.server.auth.authenticate
|
||||||
|
import io.ktor.server.request.receive
|
||||||
|
import io.ktor.server.response.respond
|
||||||
import io.ktor.server.response.respondBytes
|
import io.ktor.server.response.respondBytes
|
||||||
import io.ktor.server.routing.*
|
import io.ktor.server.routing.*
|
||||||
import kotlinx.serialization.builtins.nullable
|
import kotlinx.serialization.builtins.nullable
|
||||||
@ -15,47 +18,33 @@ import kotlinx.serialization.builtins.nullable
|
|||||||
class FilesRoutingConfigurator(
|
class FilesRoutingConfigurator(
|
||||||
private val filesStorage: ReadFilesStorage,
|
private val filesStorage: ReadFilesStorage,
|
||||||
private val writeFilesStorage: WriteFilesStorage?,
|
private val writeFilesStorage: WriteFilesStorage?,
|
||||||
private val unifierRouter: UnifiedRouter
|
|
||||||
) : ApplicationRoutingConfigurator.Element {
|
) : ApplicationRoutingConfigurator.Element {
|
||||||
constructor(filesStorage: FilesStorage, unifierRouter: UnifiedRouter) : this(filesStorage, filesStorage, unifierRouter)
|
constructor(filesStorage: FilesStorage) : this(filesStorage, filesStorage)
|
||||||
|
|
||||||
override fun Route.invoke() {
|
override fun Route.invoke() {
|
||||||
authenticate {
|
authenticate {
|
||||||
route(filesRootPathPart) {
|
route(filesRootPathPart) {
|
||||||
configureReadStandardCrudRepoRoutes(
|
configureReadCRUDRepoRoutes(
|
||||||
filesStorage,
|
filesStorage,
|
||||||
MetaFileInfoStorageWrapper.serializer(),
|
::FileId
|
||||||
MetaFileInfoStorageWrapper.serializer().nullable,
|
|
||||||
FileId.serializer(),
|
|
||||||
unifierRouter
|
|
||||||
)
|
)
|
||||||
writeFilesStorage ?.let {
|
writeFilesStorage ?.let {
|
||||||
configureWriteStandardCrudRepoRoutes(
|
configureWriteCRUDRepoRoutes(writeFilesStorage)
|
||||||
writeFilesStorage,
|
|
||||||
FullFileInfoStorageWrapper.serializer(),
|
|
||||||
FullFileInfoStorageWrapper.serializer().nullable,
|
|
||||||
FullFileInfo.serializer(),
|
|
||||||
FileId.serializer(),
|
|
||||||
unifierRouter
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unifierRouter.apply {
|
|
||||||
post(filesGetFilesPathPart) {
|
post(filesGetFilesPathPart) {
|
||||||
call.respondBytes(
|
call.respondBytes(
|
||||||
filesStorage.getBytes(
|
filesStorage.getBytes(
|
||||||
uniload(FileId.serializer())
|
call.receive()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
get(filesGetFullFileInfoPathPart) {
|
get(filesGetFullFileInfoPathPart) {
|
||||||
unianswer(
|
call.respond(
|
||||||
FullFileInfoStorageWrapper.serializer().nullable,
|
|
||||||
filesStorage.getFullFileInfo(
|
filesStorage.getFullFileInfo(
|
||||||
decodeUrlQueryValueOrSendError(filesFileIdParameter, FileId.serializer()) ?: return@get
|
FileId(call.getParameterOrSendError(filesFileIdParameter) ?.decodeURLQueryComponent() ?: return@get)
|
||||||
|
) ?: HttpStatusCode.NoContent
|
||||||
)
|
)
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,12 +6,12 @@ import kotlinx.serialization.KSerializer
|
|||||||
|
|
||||||
class ClientRolesStorage<T : Role>(
|
class ClientRolesStorage<T : Role>(
|
||||||
private val baseUrl: String,
|
private val baseUrl: String,
|
||||||
private val unifiedRequester: UnifiedRequester,
|
private val client: HttpClient,
|
||||||
private val serializer: KSerializer<T>
|
private val serializer: KSerializer<T>
|
||||||
) : RolesStorage<T>,
|
) : RolesStorage<T>,
|
||||||
ReadRolesStorage<T> by ReadClientRolesStorage(
|
ReadRolesStorage<T> by ReadClientRolesStorage(
|
||||||
baseUrl, unifiedRequester, serializer
|
baseUrl, client, serializer
|
||||||
),
|
),
|
||||||
WriteRolesStorage<T> by WriteClientRolesStorage(
|
WriteRolesStorage<T> by WriteClientRolesStorage(
|
||||||
baseUrl, unifiedRequester, serializer
|
baseUrl, client, serializer
|
||||||
)
|
)
|
||||||
|
@ -3,13 +3,15 @@ package dev.inmo.postssystem.features.roles.client
|
|||||||
import dev.inmo.postssystem.features.roles.common.*
|
import dev.inmo.postssystem.features.roles.common.*
|
||||||
import dev.inmo.micro_utils.ktor.client.UnifiedRequester
|
import dev.inmo.micro_utils.ktor.client.UnifiedRequester
|
||||||
import dev.inmo.micro_utils.ktor.common.buildStandardUrl
|
import dev.inmo.micro_utils.ktor.common.buildStandardUrl
|
||||||
|
import io.ktor.client.HttpClient
|
||||||
|
import io.ktor.client.request.get
|
||||||
import kotlinx.serialization.KSerializer
|
import kotlinx.serialization.KSerializer
|
||||||
import kotlinx.serialization.builtins.ListSerializer
|
import kotlinx.serialization.builtins.ListSerializer
|
||||||
import kotlinx.serialization.builtins.serializer
|
import kotlinx.serialization.builtins.serializer
|
||||||
|
|
||||||
class ReadClientRolesStorage<T : Role>(
|
class ReadClientRolesStorage<T : Role>(
|
||||||
private val baseUrl: String,
|
private val baseUrl: String,
|
||||||
private val unifiedRequester: UnifiedRequester,
|
private val client: HttpClient,
|
||||||
private val serializer: KSerializer<T>
|
private val serializer: KSerializer<T>
|
||||||
) : ReadRolesStorage<T> {
|
) : ReadRolesStorage<T> {
|
||||||
private val userRolesSerializer = ListSerializer(serializer)
|
private val userRolesSerializer = ListSerializer(serializer)
|
||||||
@ -21,14 +23,13 @@ class ReadClientRolesStorage<T : Role>(
|
|||||||
|
|
||||||
override suspend fun getSubjects(
|
override suspend fun getSubjects(
|
||||||
role: T
|
role: T
|
||||||
): List<RoleSubject> = unifiedRequester.uniget(
|
): List<RoleSubject> = client.get(
|
||||||
buildStandardUrl(
|
buildStandardUrl(
|
||||||
userRolesFullUrl,
|
userRolesFullUrl,
|
||||||
usersRolesGetSubjectsPathPart,
|
usersRolesGetSubjectsPathPart,
|
||||||
usersRolesRoleQueryParameterName to unifiedRequester.encodeUrlQueryValue(serializer, role)
|
usersRolesRoleQueryParameterName to unifiedRequester.encodeUrlQueryValue(serializer, role)
|
||||||
),
|
|
||||||
RoleSubjectsSerializer
|
|
||||||
)
|
)
|
||||||
|
).body()
|
||||||
|
|
||||||
override suspend fun getRoles(
|
override suspend fun getRoles(
|
||||||
subject: RoleSubject
|
subject: RoleSubject
|
||||||
|
@ -8,7 +8,7 @@ import kotlinx.serialization.builtins.serializer
|
|||||||
|
|
||||||
class WriteClientRolesStorage<T : Role>(
|
class WriteClientRolesStorage<T : Role>(
|
||||||
private val baseUrl: String,
|
private val baseUrl: String,
|
||||||
private val unifiedRequester: UnifiedRequester,
|
private val client: HttpClient,
|
||||||
private val serializer: KSerializer<T>
|
private val serializer: KSerializer<T>
|
||||||
) : WriteRolesStorage<T> {
|
) : WriteRolesStorage<T> {
|
||||||
private val wrapperSerializer = RolesStorageIncludeExcludeWrapper.serializer(
|
private val wrapperSerializer = RolesStorageIncludeExcludeWrapper.serializer(
|
||||||
|
@ -6,7 +6,7 @@ import kotlinx.serialization.descriptors.SerialDescriptor
|
|||||||
import kotlinx.serialization.encoding.*
|
import kotlinx.serialization.encoding.*
|
||||||
import kotlinx.serialization.json.*
|
import kotlinx.serialization.json.*
|
||||||
|
|
||||||
@Serializable(RoleSerializer::class)
|
@Polymorphic
|
||||||
interface Role {
|
interface Role {
|
||||||
companion object {
|
companion object {
|
||||||
fun serializer(): KSerializer<Role> = RoleSerializer
|
fun serializer(): KSerializer<Role> = RoleSerializer
|
||||||
|
@ -1,17 +1,14 @@
|
|||||||
package dev.inmo.postssystem.features.roles.manager.server
|
package dev.inmo.postssystem.features.roles.manager.server
|
||||||
|
|
||||||
import dev.inmo.micro_utils.ktor.server.UnifiedRouter
|
|
||||||
import dev.inmo.postssystem.features.roles.common.RolesStorage
|
import dev.inmo.postssystem.features.roles.common.RolesStorage
|
||||||
import dev.inmo.postssystem.features.roles.manager.common.RolesManagerRole
|
import dev.inmo.postssystem.features.roles.manager.common.RolesManagerRole
|
||||||
import dev.inmo.postssystem.features.roles.server.RolesStorageWriteServerRoutesConfigurator
|
import dev.inmo.postssystem.features.roles.server.RolesStorageWriteServerRoutesConfigurator
|
||||||
import dev.inmo.micro_utils.ktor.server.configurators.ApplicationRoutingConfigurator
|
import dev.inmo.micro_utils.ktor.server.configurators.ApplicationRoutingConfigurator
|
||||||
|
|
||||||
class RolesManagerRolesStorageServerRoutesConfigurator(
|
class RolesManagerRolesStorageServerRoutesConfigurator(
|
||||||
storage: RolesStorage<RolesManagerRole>,
|
storage: RolesStorage<RolesManagerRole>
|
||||||
unifiedRouter: UnifiedRouter
|
|
||||||
) : ApplicationRoutingConfigurator.Element by RolesStorageWriteServerRoutesConfigurator(
|
) : ApplicationRoutingConfigurator.Element by RolesStorageWriteServerRoutesConfigurator(
|
||||||
storage,
|
storage,
|
||||||
RolesManagerRole.serializer(),
|
RolesManagerRole.serializer(),
|
||||||
RolesManagerRolesChecker.key,
|
RolesManagerRolesChecker.key
|
||||||
unifiedRouter = unifiedRouter
|
|
||||||
)
|
)
|
||||||
|
@ -12,8 +12,7 @@ class RolesStorageWriteServerRoutesConfigurator<T : Role>(
|
|||||||
private val storage: WriteRolesStorage<T>,
|
private val storage: WriteRolesStorage<T>,
|
||||||
private val serializer: KSerializer<T>,
|
private val serializer: KSerializer<T>,
|
||||||
private val includeAuthKey: String,
|
private val includeAuthKey: String,
|
||||||
private val excludeAuthKey: String = includeAuthKey,
|
private val excludeAuthKey: String = includeAuthKey
|
||||||
private val unifiedRouter: UnifiedRouter
|
|
||||||
) : ApplicationRoutingConfigurator.Element {
|
) : ApplicationRoutingConfigurator.Element {
|
||||||
override fun Route.invoke() {
|
override fun Route.invoke() {
|
||||||
route(usersRolesRootPathPart) {
|
route(usersRolesRootPathPart) {
|
||||||
|
@ -11,8 +11,7 @@ import kotlinx.serialization.builtins.serializer
|
|||||||
|
|
||||||
class RolesStorageReadServerRoutesConfigurator<T : Role>(
|
class RolesStorageReadServerRoutesConfigurator<T : Role>(
|
||||||
private val storage: ReadRolesStorage<T>,
|
private val storage: ReadRolesStorage<T>,
|
||||||
private val serializer: KSerializer<T>,
|
private val serializer: KSerializer<T>
|
||||||
private val unifiedRouter: UnifiedRouter
|
|
||||||
) : ApplicationRoutingConfigurator.Element {
|
) : ApplicationRoutingConfigurator.Element {
|
||||||
private val userRolesSerializer = ListSerializer(serializer)
|
private val userRolesSerializer = ListSerializer(serializer)
|
||||||
override fun Route.invoke() {
|
override fun Route.invoke() {
|
||||||
|
@ -9,10 +9,10 @@ import kotlinx.serialization.builtins.nullable
|
|||||||
|
|
||||||
class UsersStorageKtorClient(
|
class UsersStorageKtorClient(
|
||||||
baseUrl: String,
|
baseUrl: String,
|
||||||
unifiedRequester: UnifiedRequester
|
client: HttpClient
|
||||||
) : ReadUsersStorage, ReadCRUDRepo<User, UserId> by KtorReadStandardCrudRepo(
|
) : ReadUsersStorage, ReadCRUDRepo<User, UserId> by KtorReadStandardCrudRepo(
|
||||||
buildStandardUrl(baseUrl, usersServerPathPart),
|
buildStandardUrl(baseUrl, usersServerPathPart),
|
||||||
unifiedRequester,
|
client,
|
||||||
User.serializer(),
|
User.serializer(),
|
||||||
User.serializer().nullable,
|
User.serializer().nullable,
|
||||||
UserId.serializer()
|
UserId.serializer()
|
||||||
|
@ -1,28 +1,21 @@
|
|||||||
package dev.inmo.postssystem.features.users.server
|
package dev.inmo.postssystem.features.users.server
|
||||||
|
|
||||||
import dev.inmo.micro_utils.ktor.server.UnifiedRouter
|
|
||||||
import dev.inmo.postssystem.features.users.common.*
|
import dev.inmo.postssystem.features.users.common.*
|
||||||
import dev.inmo.micro_utils.ktor.server.configurators.ApplicationRoutingConfigurator
|
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.configureReadCRUDRepoRoutes
|
||||||
import io.ktor.server.auth.authenticate
|
import io.ktor.server.auth.authenticate
|
||||||
import io.ktor.server.routing.Route
|
import io.ktor.server.routing.Route
|
||||||
import io.ktor.server.routing.route
|
import io.ktor.server.routing.route
|
||||||
import kotlinx.serialization.builtins.nullable
|
|
||||||
|
|
||||||
class UsersStorageServerRoutesConfigurator(
|
class UsersStorageServerRoutesConfigurator(
|
||||||
private val usersStorage: ReadUsersStorage,
|
private val usersStorage: ReadUsersStorage
|
||||||
private val unifiedRouter: UnifiedRouter
|
|
||||||
) : ApplicationRoutingConfigurator.Element {
|
) : ApplicationRoutingConfigurator.Element {
|
||||||
override fun Route.invoke() {
|
override fun Route.invoke() {
|
||||||
authenticate {
|
authenticate {
|
||||||
route(usersServerPathPart) {
|
route(usersServerPathPart) {
|
||||||
configureReadStandardCrudRepoRoutes(
|
configureReadCRUDRepoRoutes(
|
||||||
usersStorage,
|
usersStorage
|
||||||
User.serializer(),
|
) { UserId(it.toLong()) }
|
||||||
User.serializer().nullable,
|
|
||||||
UserId.serializer(),
|
|
||||||
unifiedRouter
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ import kotlinx.serialization.builtins.serializer
|
|||||||
|
|
||||||
class SimplePublicatorServiceClient(
|
class SimplePublicatorServiceClient(
|
||||||
baseUrl: String,
|
baseUrl: String,
|
||||||
private val unifiedRequester: UnifiedRequester
|
private val client: HttpClient
|
||||||
) : SimplePublicatorService {
|
) : SimplePublicatorService {
|
||||||
private val fullUrl = buildStandardUrl(
|
private val fullUrl = buildStandardUrl(
|
||||||
baseUrl,
|
baseUrl,
|
||||||
|
@ -18,11 +18,10 @@ import dev.inmo.postssystem.features.status.server.StatusRoutingConfigurator
|
|||||||
import dev.inmo.postssystem.features.users.common.ExposedUsersStorage
|
import dev.inmo.postssystem.features.users.common.ExposedUsersStorage
|
||||||
import dev.inmo.postssystem.features.users.server.UsersStorageServerRoutesConfigurator
|
import dev.inmo.postssystem.features.users.server.UsersStorageServerRoutesConfigurator
|
||||||
import dev.inmo.micro_utils.coroutines.LinkedSupervisorScope
|
import dev.inmo.micro_utils.coroutines.LinkedSupervisorScope
|
||||||
import dev.inmo.micro_utils.ktor.server.UnifiedRouter
|
|
||||||
import dev.inmo.micro_utils.ktor.server.configurators.*
|
import dev.inmo.micro_utils.ktor.server.configurators.*
|
||||||
import dev.inmo.micro_utils.ktor.server.createKtorServer
|
import dev.inmo.micro_utils.ktor.server.createKtorServer
|
||||||
import dev.inmo.micro_utils.repos.exposed.keyvalue.ExposedKeyValueRepo
|
import dev.inmo.micro_utils.repos.exposed.keyvalue.ExposedKeyValueRepo
|
||||||
import dev.inmo.micro_utils.repos.exposed.onetomany.ExposedOneToManyKeyValueRepo
|
import dev.inmo.micro_utils.repos.exposed.onetomany.ExposedKeyValuesRepo
|
||||||
import dev.inmo.postssystem.features.common.common.*
|
import dev.inmo.postssystem.features.common.common.*
|
||||||
import dev.inmo.postssystem.features.common.server.Qualifiers
|
import dev.inmo.postssystem.features.common.server.Qualifiers
|
||||||
import dev.inmo.postssystem.features.content.common.*
|
import dev.inmo.postssystem.features.content.common.*
|
||||||
@ -88,8 +87,6 @@ fun getDIModule(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
single { UnifiedRouter(get()) }
|
|
||||||
|
|
||||||
singleWithBinds { config }
|
singleWithBinds { config }
|
||||||
singleWithBinds { get<Config>().databaseConfig }
|
singleWithBinds { get<Config>().databaseConfig }
|
||||||
singleWithBinds { get<Config>().authConfig }
|
singleWithBinds { get<Config>().authConfig }
|
||||||
@ -101,7 +98,7 @@ fun getDIModule(
|
|||||||
singleWithBinds { exposedUsersAuthenticator(get(), get()) }
|
singleWithBinds { exposedUsersAuthenticator(get(), get()) }
|
||||||
|
|
||||||
factory<KeyValuesRolesOriginalRepo>(Qualifiers.usersRolesKeyValueFactoryQualifier) { (tableName: String) ->
|
factory<KeyValuesRolesOriginalRepo>(Qualifiers.usersRolesKeyValueFactoryQualifier) { (tableName: String) ->
|
||||||
ExposedOneToManyKeyValueRepo(get(), { text("subject") }, { text("role") }, tableName)
|
ExposedKeyValuesRepo(get(), { text("subject") }, { text("role") }, tableName)
|
||||||
}
|
}
|
||||||
single {
|
single {
|
||||||
RolesManagerRoleStorage(get(Qualifiers.usersRolesKeyValueFactoryQualifier) { ParametersHolder(mutableListOf("rolesManager")) })
|
RolesManagerRoleStorage(get(Qualifiers.usersRolesKeyValueFactoryQualifier) { ParametersHolder(mutableListOf("rolesManager")) })
|
||||||
@ -154,12 +151,12 @@ fun getDIModule(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Routing configurators
|
// Routing configurators
|
||||||
singleWithBinds { FilesRoutingConfigurator(get(), null, get()) }
|
singleWithBinds { FilesRoutingConfigurator(get(), null) }
|
||||||
singleWithBinds { StatusRoutingConfigurator }
|
singleWithBinds { StatusRoutingConfigurator }
|
||||||
singleWithBinds { UsersStorageServerRoutesConfigurator(get(), get()) }
|
singleWithBinds { UsersStorageServerRoutesConfigurator(get()) }
|
||||||
singleWithBinds { RolesStorageReadServerRoutesConfigurator<Role>(get(), RoleSerializer, get()) }
|
singleWithBinds { RolesStorageReadServerRoutesConfigurator<Role>(get(), RoleSerializer) }
|
||||||
singleWithBinds { RolesManagerRolesStorageServerRoutesConfigurator(get(), get()) }
|
singleWithBinds { RolesManagerRolesStorageServerRoutesConfigurator(get()) }
|
||||||
singleWithBinds { ServerPostsServiceRoutingConfigurator(get(), get(), get(), get()) }
|
singleWithBinds { ServerPostsServiceRoutingConfigurator(get(), get(), get()) }
|
||||||
|
|
||||||
singleWithBinds { ClientStaticRoutingConfiguration("web") }
|
singleWithBinds { ClientStaticRoutingConfiguration("web") }
|
||||||
singleWithBinds {
|
singleWithBinds {
|
||||||
@ -181,7 +178,7 @@ fun getDIModule(
|
|||||||
get()
|
get()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
singleWithBinds { AuthenticationRoutingConfigurator(get(), get(), get()) }
|
singleWithBinds { AuthenticationRoutingConfigurator(get(), get()) }
|
||||||
singleWithBinds { NotFoundStatusPageRedirectToIndex("/") }
|
singleWithBinds { NotFoundStatusPageRedirectToIndex("/") }
|
||||||
|
|
||||||
if (config.debugMode) {
|
if (config.debugMode) {
|
||||||
|
@ -5,7 +5,7 @@ import dev.inmo.postssystem.services.posts.common.*
|
|||||||
|
|
||||||
class ClientPostsService(
|
class ClientPostsService(
|
||||||
baseUrl: String,
|
baseUrl: String,
|
||||||
unifiedRequester: UnifiedRequester
|
client: HttpClient
|
||||||
) : PostsService,
|
) : PostsService,
|
||||||
ReadPostsService by ClientReadPostsService(baseUrl, unifiedRequester),
|
ReadPostsService by ClientReadPostsService(baseUrl, client),
|
||||||
WritePostsService by ClientWritePostsService(baseUrl, unifiedRequester)
|
WritePostsService by ClientWritePostsService(baseUrl, client)
|
||||||
|
@ -12,10 +12,10 @@ import kotlinx.serialization.builtins.nullable
|
|||||||
|
|
||||||
class ClientReadPostsService(
|
class ClientReadPostsService(
|
||||||
private val baseUrl: String,
|
private val baseUrl: String,
|
||||||
private val unifiedRequester: UnifiedRequester
|
private val client: HttpClient
|
||||||
) : ReadPostsService, ReadCRUDRepo<RegisteredPost, PostId> by KtorReadStandardCrudRepo(
|
) : ReadPostsService, ReadCRUDRepo<RegisteredPost, PostId> by KtorReadStandardCrudRepo(
|
||||||
buildStandardUrl(baseUrl, postsRootPath),
|
buildStandardUrl(baseUrl, postsRootPath),
|
||||||
unifiedRequester,
|
client,
|
||||||
RegisteredPost.serializer(),
|
RegisteredPost.serializer(),
|
||||||
RegisteredPost.serializer().nullable,
|
RegisteredPost.serializer().nullable,
|
||||||
PostId.serializer()
|
PostId.serializer()
|
||||||
|
@ -25,17 +25,17 @@ import kotlinx.serialization.modules.polymorphic
|
|||||||
|
|
||||||
class ClientWritePostsService(
|
class ClientWritePostsService(
|
||||||
private val baseUrl: String,
|
private val baseUrl: String,
|
||||||
unifiedRequester: UnifiedRequester
|
client: HttpClient
|
||||||
) : WritePostsService {
|
) : WritePostsService {
|
||||||
private val root = buildStandardUrl(baseUrl, postsRootPath)
|
private val root = buildStandardUrl(baseUrl, postsRootPath)
|
||||||
private val unifiedRequester = UnifiedRequester(
|
// private val unifiedRequester = UnifiedRequester(
|
||||||
unifiedRequester.client,
|
// unifiedRequester.client,
|
||||||
unifiedRequester.serialFormat.createWithSerializerModuleExtension {
|
// unifiedRequester.serialFormat.createWithSerializerModuleExtension {
|
||||||
polymorphic(Content::class) {
|
// polymorphic(Content::class) {
|
||||||
subclass(BinaryContent::class, BinaryContentSerializer(TempFileIdentifierInputProvider::class, TempFileIdentifierInputProvider.serializer()))
|
// subclass(BinaryContent::class, BinaryContentSerializer(TempFileIdentifierInputProvider::class, TempFileIdentifierInputProvider.serializer()))
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
)
|
// )
|
||||||
|
|
||||||
private val contentEitherSerializer = EitherSerializer(ContentId.serializer(), ContentSerializer)
|
private val contentEitherSerializer = EitherSerializer(ContentId.serializer(), ContentSerializer)
|
||||||
private val contentsEitherSerializer = ListSerializer(contentEitherSerializer)
|
private val contentsEitherSerializer = ListSerializer(contentEitherSerializer)
|
||||||
@ -58,7 +58,7 @@ class ClientWritePostsService(
|
|||||||
return (content as? BinaryContent) ?.let {
|
return (content as? BinaryContent) ?.let {
|
||||||
when (val provider = it.inputProvider) {
|
when (val provider = it.inputProvider) {
|
||||||
is FileBasedInputProvider -> {
|
is FileBasedInputProvider -> {
|
||||||
val fileId = unifiedRequester.tempUpload(
|
val fileId = client.tempUpload(
|
||||||
tempUploadFullPath,
|
tempUploadFullPath,
|
||||||
provider.file
|
provider.file
|
||||||
)
|
)
|
||||||
|
@ -10,7 +10,7 @@ import dev.inmo.micro_utils.mime_types.findBuiltinMimeType
|
|||||||
import dev.inmo.micro_utils.repos.ktor.common.crud.createRouting
|
import dev.inmo.micro_utils.repos.ktor.common.crud.createRouting
|
||||||
import dev.inmo.micro_utils.repos.ktor.common.crud.updateRouting
|
import dev.inmo.micro_utils.repos.ktor.common.crud.updateRouting
|
||||||
import dev.inmo.micro_utils.repos.ktor.common.one_to_many.removeRoute
|
import dev.inmo.micro_utils.repos.ktor.common.one_to_many.removeRoute
|
||||||
import dev.inmo.micro_utils.repos.ktor.server.crud.configureReadStandardCrudRepoRoutes
|
import dev.inmo.micro_utils.repos.ktor.server.crud.configureReadCRUDRepoRoutes
|
||||||
import dev.inmo.postssystem.features.common.common.FileBasedInputProvider
|
import dev.inmo.postssystem.features.common.common.FileBasedInputProvider
|
||||||
import dev.inmo.postssystem.features.content.common.*
|
import dev.inmo.postssystem.features.content.common.*
|
||||||
import dev.inmo.postssystem.features.files.common.FileId
|
import dev.inmo.postssystem.features.files.common.FileId
|
||||||
@ -22,6 +22,7 @@ import io.ktor.http.content.streamProvider
|
|||||||
import io.ktor.server.application.ApplicationCall
|
import io.ktor.server.application.ApplicationCall
|
||||||
import io.ktor.server.application.call
|
import io.ktor.server.application.call
|
||||||
import io.ktor.server.auth.authenticate
|
import io.ktor.server.auth.authenticate
|
||||||
|
import io.ktor.server.request.receive
|
||||||
import io.ktor.server.request.receiveMultipart
|
import io.ktor.server.request.receiveMultipart
|
||||||
import io.ktor.server.response.respond
|
import io.ktor.server.response.respond
|
||||||
import io.ktor.server.routing.*
|
import io.ktor.server.routing.*
|
||||||
@ -32,8 +33,6 @@ import io.ktor.utils.io.streams.asInput
|
|||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import kotlinx.coroutines.sync.Mutex
|
import kotlinx.coroutines.sync.Mutex
|
||||||
import kotlinx.coroutines.sync.withLock
|
import kotlinx.coroutines.sync.withLock
|
||||||
import kotlinx.serialization.builtins.*
|
|
||||||
import kotlinx.serialization.modules.polymorphic
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import java.nio.file.attribute.FileTime
|
import java.nio.file.attribute.FileTime
|
||||||
@ -42,19 +41,8 @@ import java.util.concurrent.TimeUnit
|
|||||||
class ServerPostsServiceRoutingConfigurator(
|
class ServerPostsServiceRoutingConfigurator(
|
||||||
private val readPostsService: ReadPostsService,
|
private val readPostsService: ReadPostsService,
|
||||||
private val writePostsService: WritePostsService? = readPostsService as? WritePostsService,
|
private val writePostsService: WritePostsService? = readPostsService as? WritePostsService,
|
||||||
private val scope: CoroutineScope,
|
private val scope: CoroutineScope
|
||||||
unifiedRouter: UnifiedRouter
|
|
||||||
) : ApplicationRoutingConfigurator.Element {
|
) : ApplicationRoutingConfigurator.Element {
|
||||||
private val unifiedRouter = UnifiedRouter(
|
|
||||||
serialFormat = unifiedRouter.serialFormat.createWithSerializerModuleExtension {
|
|
||||||
polymorphic(Content::class) {
|
|
||||||
subclass(BinaryContent::class, BinaryContentSerializer(TempFileIdentifierInputProvider::class, TempFileIdentifierInputProvider.serializer()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
private val contentEitherSerializer = EitherSerializer(ContentId.serializer(), ContentSerializer)
|
|
||||||
private val contentsEitherSerializer = ListSerializer(contentEitherSerializer)
|
|
||||||
private val contentsSerializer = ListSerializer(ContentSerializer)
|
|
||||||
|
|
||||||
private val temporalFilesMap = mutableMapOf<FileId, MPPFile>()
|
private val temporalFilesMap = mutableMapOf<FileId, MPPFile>()
|
||||||
private val temporalFilesMutex = Mutex()
|
private val temporalFilesMutex = Mutex()
|
||||||
@ -97,68 +85,52 @@ class ServerPostsServiceRoutingConfigurator(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun PipelineContext<Unit, ApplicationCall>.receiveContents(): List<Content> {
|
private suspend fun PipelineContext<Unit, ApplicationCall>.receiveContents(): List<Content> {
|
||||||
return unifiedRouter.run {
|
return call.receive<ContentsWrapper>().content.mapNotNull {
|
||||||
uniload(contentsSerializer).mapNotNull {
|
|
||||||
mapBinary(it as? BinaryContent ?: return@mapNotNull it)
|
mapBinary(it as? BinaryContent ?: return@mapNotNull it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private suspend fun PipelineContext<Unit, ApplicationCall>.receiveContentsEithers(): List<Either<ContentId, Content>> {
|
private suspend fun PipelineContext<Unit, ApplicationCall>.receiveContentsEithers(): List<Either<ContentId, Content>> {
|
||||||
return unifiedRouter.run {
|
return call.receive<ContentsEithersWrapper>().content.mapNotNull {
|
||||||
uniload(contentsEitherSerializer).mapNotNull {
|
|
||||||
it.mapOnSecond {
|
it.mapOnSecond {
|
||||||
mapBinary(it as? BinaryContent ?: return@mapOnSecond null) ?.either()
|
mapBinary(it as? BinaryContent ?: return@mapOnSecond null) ?.either()
|
||||||
} ?: it
|
} ?: it
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
override fun Route.invoke() {
|
override fun Route.invoke() {
|
||||||
authenticate {
|
authenticate {
|
||||||
route(postsRootPath) {
|
route(postsRootPath) {
|
||||||
configureReadStandardCrudRepoRoutes(
|
configureReadCRUDRepoRoutes(
|
||||||
readPostsService,
|
readPostsService
|
||||||
RegisteredPost.serializer(),
|
) { PostId(it.toLong()) }
|
||||||
RegisteredPost.serializer().nullable,
|
|
||||||
PostId.serializer(),
|
|
||||||
unifiedRouter
|
|
||||||
)
|
|
||||||
|
|
||||||
writePostsService ?.let {
|
writePostsService ?.let {
|
||||||
|
|
||||||
unifiedRouter.apply {
|
|
||||||
|
|
||||||
post(createRouting) {
|
post(createRouting) {
|
||||||
val data = receiveContents()
|
val data = receiveContents()
|
||||||
|
|
||||||
unianswer(
|
call.respond(
|
||||||
RegisteredPost.serializer().nullable,
|
writePostsService.create(FullNewPost(data)) ?: HttpStatusCode.NoContent
|
||||||
writePostsService.create(FullNewPost(data))
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
post(updateRouting) {
|
post(updateRouting) {
|
||||||
val postId = call.decodeUrlQueryValueOrSendError(postsPostIdParameter, PostId.serializer()) ?: return@post
|
call.respond(
|
||||||
val data = receiveContentsEithers()
|
|
||||||
|
|
||||||
unianswer(
|
|
||||||
RegisteredPost.serializer().nullable,
|
|
||||||
writePostsService.update(
|
writePostsService.update(
|
||||||
postId,
|
call.getQueryParameterOrSendError(postsPostIdParameter)?.toLong()?.let(::PostId) ?: return@post,
|
||||||
data
|
receiveContentsEithers()
|
||||||
)
|
) ?: HttpStatusCode.NoContent
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
post(removeRoute) {
|
post(removeRoute) {
|
||||||
val postId = uniload(PostId.serializer())
|
call.respond(
|
||||||
|
writePostsService.remove(
|
||||||
unianswer(
|
call.receive()
|
||||||
Unit.serializer(),
|
)
|
||||||
writePostsService.remove(postId)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,8 +170,6 @@ class ServerPostsServiceRoutingConfigurator(
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user