add content

This commit is contained in:
2021-11-24 20:25:05 +06:00
parent fffe99adaa
commit 58b7e973be
24 changed files with 398 additions and 176 deletions
client
build.gradle
src
commonMain
kotlin
dev
inmo
postssystem
client
features
auth
server
src
jvmMain
kotlin
dev
inmo
postssystem
common
common
src
commonMain
jvmMain
kotlin
dev
inmo
postssystem
features
content
files
server
src
jvmMain
kotlin
dev
inmo
postssystem
features
roles
manager
server
src
jvmMain
kotlin
dev
inmo
server
users
server
src
jvmMain
kotlin
dev
inmo
postssystem
server
build.gradle
src
main
java
dev
inmo
postssystem
server
settings.gradle

@ -20,6 +20,7 @@ kotlin {
api project(":postssystem.features.auth.client")
api project(":postssystem.features.roles.client")
api project(":postssystem.features.roles.manager.client")
api project(":postssystem.features.content.client")
api "dev.inmo:micro_utils.fsm.common:$microutils_version"
api "dev.inmo:micro_utils.fsm.repos.common:$microutils_version"
api "dev.inmo:micro_utils.crypto:$microutils_version"

@ -24,13 +24,19 @@ import dev.inmo.postssystem.client.settings.DefaultSettings
import dev.inmo.postssystem.client.settings.Settings
import dev.inmo.postssystem.client.settings.auth.AuthSettings
import dev.inmo.postssystem.client.settings.auth.DefaultAuthSettings
import dev.inmo.postssystem.features.common.common.SerializersModuleConfigurator
import dev.inmo.postssystem.features.common.common.singleWithRandomQualifier
import dev.inmo.postssystem.features.content.common.ContentSerializersModuleConfigurator
import dev.inmo.postssystem.features.content.common.OtherContentSerializerModuleConfigurator
import dev.inmo.postssystem.features.status.client.StatusFeatureClient
import io.ktor.client.HttpClient
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.serialization.BinaryFormat
import kotlinx.serialization.StringFormat
import kotlinx.serialization.cbor.Cbor
import kotlinx.serialization.json.Json
import kotlinx.serialization.modules.SerializersModule
import org.koin.core.Koin
import org.koin.core.context.startKoin
import org.koin.core.module.Module
@ -41,7 +47,6 @@ import org.koin.dsl.module
val UIScopeQualifier = StringQualifier("CoroutineScopeUI")
val SettingsQualifier = StringQualifier("Settings")
val UserRolesQualifier = StringQualifier("UserRoles")
private val DBDropperQualifier = StringQualifier("DBDropper")
private val FSMHandlersBuilderQualifier = StringQualifier("FSMHandlersBuilder")
val defaultSerialFormat = Json {
@ -61,7 +66,18 @@ fun baseKoin(
): Koin = startKoin {
modules(
module {
single<StringFormat> { defaultSerialFormat }
singleWithRandomQualifier<ContentSerializersModuleConfigurator.Element> { OtherContentSerializerModuleConfigurator }
singleWithRandomQualifier<SerializersModuleConfigurator.Element> { ContentSerializersModuleConfigurator(getAll()) }
single { SerializersModuleConfigurator(getAll()) }
single {
Json {
ignoreUnknownKeys = true
serializersModule = SerializersModule { get<SerializersModuleConfigurator>().apply { invoke() } }
}
}
single<StringFormat> { get<Json>() }
single(SettingsQualifier) { settingsFactory() }
single { DBDropper(get(SettingsQualifier)) }
single(FSMHandlersBuilderQualifier) { handlersSetter }
@ -102,7 +118,11 @@ fun getAuthorizedFeaturesDIModule(
}
single(credsQualifier) { initialAuthKey }
single(serverUrlQualifier) { serverUrl }
single<BinaryFormat> { standardKtorSerialFormat }
single<BinaryFormat> {
Cbor {
serializersModule = SerializersModule { get<SerializersModuleConfigurator>().apply { invoke() } }
}
}
single { UnifiedRequester(get(), get()) }
single { StatusFeatureClient(get(serverUrlQualifier), get()) }

@ -5,9 +5,8 @@ import dev.inmo.postssystem.features.auth.server.tokens.AuthTokensService
import dev.inmo.postssystem.features.common.server.sessions.ApplicationAuthenticationConfigurator
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 dev.inmo.micro_utils.ktor.server.unianswer
import dev.inmo.micro_utils.ktor.server.uniload
import io.ktor.application.*
import io.ktor.auth.*
import io.ktor.http.HttpStatusCode
@ -25,81 +24,84 @@ fun User.principal() = AuthUserPrincipal(this)
class AuthenticationRoutingConfigurator(
private val authFeature: AuthFeature,
private val authTokensService: AuthTokensService
private val authTokensService: AuthTokensService,
private val unifiedRouter: UnifiedRouter
) : ApplicationRoutingConfigurator.Element, ApplicationAuthenticationConfigurator.Element {
override fun Route.invoke() {
route(authRootPathPart) {
post(authAuthPathPart) {
safely(
{
// TODO:: add error info
it.printStackTrace()
call.respond(
HttpStatusCode.InternalServerError,
"Something went wrong"
)
}
) {
val creds = call.uniload(AuthCreds.serializer())
val tokenInfo = authFeature.auth(creds)
if (tokenInfo == null) {
if (call.response.status() == null) {
call.respond(HttpStatusCode.Forbidden)
unifiedRouter.apply {
route(authRootPathPart) {
post(authAuthPathPart) {
safely(
{
// TODO:: add error info
it.printStackTrace()
call.respond(
HttpStatusCode.InternalServerError,
"Something went wrong"
)
}
) {
val creds = uniload(AuthCreds.serializer())
val tokenInfo = authFeature.auth(creds)
if (tokenInfo == null) {
if (call.response.status() == null) {
call.respond(HttpStatusCode.Forbidden)
}
} else {
call.sessions.set(tokenSessionKey, tokenInfo.token)
unianswer(
AuthTokenInfo.serializer().nullable,
tokenInfo
)
}
} else {
call.sessions.set(tokenSessionKey, tokenInfo.token)
call.unianswer(
AuthTokenInfo.serializer().nullable,
tokenInfo
)
}
}
}
post(authRefreshPathPart) {
safely(
{
// TODO:: add error info
call.respond(
HttpStatusCode.InternalServerError,
"Something went wrong"
)
}
) {
val refreshToken = call.uniload(RefreshToken.serializer())
val tokenInfo = authFeature.refresh(refreshToken)
if (tokenInfo == null) {
if (call.response.status() == null) {
call.respond(HttpStatusCode.Forbidden)
post(authRefreshPathPart) {
safely(
{
// TODO:: add error info
call.respond(
HttpStatusCode.InternalServerError,
"Something went wrong"
)
}
) {
val refreshToken = uniload(RefreshToken.serializer())
val tokenInfo = authFeature.refresh(refreshToken)
if (tokenInfo == null) {
if (call.response.status() == null) {
call.respond(HttpStatusCode.Forbidden)
}
} else {
call.sessions.set(tokenSessionKey, tokenInfo.token)
unianswer(
AuthTokenInfo.serializer().nullable,
tokenInfo
)
}
} else {
call.sessions.set(tokenSessionKey, tokenInfo.token)
call.unianswer(
AuthTokenInfo.serializer().nullable,
tokenInfo
)
}
}
}
post(authGetMePathPart) {
safely(
{
// TODO:: add error info
call.respond(
HttpStatusCode.InternalServerError,
"Something went wrong"
post(authGetMePathPart) {
safely(
{
// TODO:: add error info
call.respond(
HttpStatusCode.InternalServerError,
"Something went wrong"
)
}
) {
unianswer(
User.serializer().nullable,
authFeature.getMe(
uniload(AuthToken.serializer())
)
)
}
) {
call.unianswer(
User.serializer().nullable,
authFeature.getMe(
call.uniload(AuthToken.serializer())
)
)
}
}
}

@ -0,0 +1,16 @@
package dev.inmo.postssystem.features.common.common
import com.benasher44.uuid.uuid4
import org.koin.core.definition.Definition
import org.koin.core.instance.InstanceFactory
import org.koin.core.module.Module
import org.koin.core.qualifier.StringQualifier
/**
* Will be useful in case you need to declare some singles with one type several types, but need to separate them and do
* not care about how :)
*/
inline fun <reified T : Any> Module.singleWithRandomQualifier(
createdAtStart: Boolean = false,
noinline definition: Definition<T>
) = single(uuid4().toString(), createdAtStart, definition)

@ -0,0 +1,11 @@
package dev.inmo.postssystem.features.common.common
import org.koin.core.definition.Definition
import org.koin.core.module.Module
import org.koin.core.qualifier.StringQualifier
inline fun <reified T : Any> Module.single(
qualifier: String,
createdAtStart: Boolean = false,
noinline definition: Definition<T>
) = single(StringQualifier(qualifier), createdAtStart, definition)

@ -0,0 +1,14 @@
package dev.inmo.postssystem.features.common.common
import kotlinx.serialization.modules.SerializersModuleBuilder
class SerializersModuleConfigurator(
private val elements: List<Element>
) {
fun interface Element {
operator fun SerializersModuleBuilder.invoke()
}
operator fun SerializersModuleBuilder.invoke() {
elements.forEach { it.apply { invoke() } }
}
}

@ -11,6 +11,6 @@ inline fun <reified T : Any> Module.singleWithBinds(
qualifier: Qualifier? = null,
createdAtStart: Boolean = false,
noinline definition: Definition<T>
): Pair<Module, InstanceFactory<*>> {
return single(qualifier, createdAtStart, definition) binds (T::class.allSuperclasses.toTypedArray())
): Pair<Module, InstanceFactory<T>> {
return single(qualifier, createdAtStart, definition)
}

@ -0,0 +1,18 @@
plugins {
id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library"
}
apply from: "$mppProjectWithSerializationPresetPath"
kotlin {
sourceSets {
commonMain {
dependencies {
api project(":postssystem.features.content.common")
api project(":postssystem.features.common.client")
}
}
}
}

@ -0,0 +1 @@
<manifest package="dev.inmo.postssystem.features.content.client"/>

@ -0,0 +1,17 @@
plugins {
id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library"
}
apply from: "$mppProjectWithSerializationPresetPath"
kotlin {
sourceSets {
commonMain {
dependencies {
api project(":postssystem.features.common.common")
}
}
}
}

@ -0,0 +1,24 @@
package dev.inmo.postssystem.features.content.common
import kotlinx.serialization.Serializable
typealias ContentId = String
/**
* Content which is planned to be registered in database
*
* @see ContentSerializersModuleConfigurator.Element
* @see ContentSerializersModuleConfigurator
*/
interface Content
/**
* Content which is already registered in database. Using its [id] you can retrieve all known
* [dev.inmo.postssystem.core.post.RegisteredPost]s by using
* [dev.inmo.postssystem.core.post.repo.ReadPostsRepo.getPostsByContent]
*/
@Serializable
data class RegisteredContent(
val id: ContentId,
val content: Content
)

@ -0,0 +1,18 @@
package dev.inmo.postssystem.features.content.common
import dev.inmo.postssystem.features.common.common.SerializersModuleConfigurator
import kotlinx.serialization.modules.*
class ContentSerializersModuleConfigurator(
private val subconfigurators: List<Element>
) : SerializersModuleConfigurator.Element {
fun interface Element {
operator fun PolymorphicModuleBuilder<Content>.invoke()
}
override fun SerializersModuleBuilder.invoke() {
polymorphic(Content::class) {
subconfigurators.forEach { it.apply { invoke() } }
}
}
}

@ -0,0 +1,19 @@
package dev.inmo.postssystem.features.content.common
import kotlinx.serialization.Serializable
import kotlinx.serialization.modules.PolymorphicModuleBuilder
/**
* That is a content which in fact just a link to another content. It would be useful in case when user wish to reuse
* some content
*/
@Serializable
data class OtherContentLinkContent(
val otherId: ContentId
) : Content
object OtherContentSerializerModuleConfigurator : ContentSerializersModuleConfigurator.Element {
override fun PolymorphicModuleBuilder<Content>.invoke() {
subclass(OtherContentLinkContent::class, OtherContentLinkContent.serializer())
}
}

@ -0,0 +1 @@
<manifest package="dev.inmo.postssystem.features.content.common"/>

@ -0,0 +1,17 @@
plugins {
id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization"
}
apply from: "$mppJavaProjectPresetPath"
kotlin {
sourceSets {
commonMain {
dependencies {
api project(":postssystem.features.content.common")
api project(":postssystem.features.common.server")
}
}
}
}

@ -14,9 +14,10 @@ import kotlinx.serialization.builtins.nullable
class FilesRoutingConfigurator(
private val filesStorage: FilesStorage,
private val writeFilesStorage: WriteFilesStorage?
private val writeFilesStorage: WriteFilesStorage?,
private val unifierRouter: UnifiedRouter
) : ApplicationRoutingConfigurator.Element {
constructor(fullFilesStorage: FullFilesStorage) : this(fullFilesStorage, fullFilesStorage)
constructor(fullFilesStorage: FullFilesStorage, unifierRouter: UnifiedRouter) : this(fullFilesStorage, fullFilesStorage, unifierRouter)
override fun Route.invoke() {
authenticate {
@ -25,7 +26,8 @@ class FilesRoutingConfigurator(
filesStorage,
MetaFileInfoStorageWrapper.serializer(),
MetaFileInfoStorageWrapper.serializer().nullable,
FileId.serializer()
FileId.serializer(),
unifierRouter
)
writeFilesStorage ?.let {
configureWriteStandardCrudRepoRoutes(
@ -33,23 +35,27 @@ class FilesRoutingConfigurator(
FullFileInfoStorageWrapper.serializer(),
FullFileInfoStorageWrapper.serializer().nullable,
FullFileInfo.serializer(),
FileId.serializer()
FileId.serializer(),
unifierRouter
)
}
post(filesGetFilesPathPart) {
call.respondBytes(
filesStorage.getBytes(
call.uniload(FileId.serializer())
unifierRouter.apply {
post(filesGetFilesPathPart) {
call.respondBytes(
filesStorage.getBytes(
uniload(FileId.serializer())
)
)
)
}
get(filesGetFullFileInfoPathPart) {
call.unianswer(
FullFileInfoStorageWrapper.serializer().nullable,
filesStorage.getFullFileInfo(
call.decodeUrlQueryValueOrSendError(filesFileIdParameter, FileId.serializer()) ?: return@get
}
get(filesGetFullFileInfoPathPart) {
unianswer(
FullFileInfoStorageWrapper.serializer().nullable,
filesStorage.getFullFileInfo(
decodeUrlQueryValueOrSendError(filesFileIdParameter, FileId.serializer()) ?: return@get
)
)
)
}
}
}
}

@ -1,5 +1,6 @@
package dev.inmo.postssystem.features.roles.manager.server
import dev.inmo.micro_utils.ktor.server.UnifiedRouter
import dev.inmo.postssystem.features.roles.common.UsersRolesStorage
import dev.inmo.postssystem.features.roles.manager.common.RolesManagerRole
import dev.inmo.postssystem.features.roles.manager.common.RolesManagerRoleSerializer
@ -7,9 +8,11 @@ import dev.inmo.postssystem.features.roles.server.UsersRolesStorageWriteServerRo
import dev.inmo.micro_utils.ktor.server.configurators.ApplicationRoutingConfigurator
class RolesManagerUsersRolesStorageServerRoutesConfigurator(
storage: UsersRolesStorage<RolesManagerRole>
storage: UsersRolesStorage<RolesManagerRole>,
unifiedRouter: UnifiedRouter
) : ApplicationRoutingConfigurator.Element by UsersRolesStorageWriteServerRoutesConfigurator(
storage,
RolesManagerRoleSerializer,
RolesManagerRolesChecker.key
RolesManagerRolesChecker.key,
unifiedRouter = unifiedRouter
)

@ -15,7 +15,7 @@ import io.ktor.response.respond
class UsersRolesAuthenticationConfigurator<T : UserRole>(
private val usersRolesStorage: UsersRolesStorage<T>,
private val authTokensService: AuthTokensService,
private val rolesCheckers: List<RolesChecker<T>>
private val rolesCheckers: List<RolesChecker<T>>,
) : ApplicationAuthenticationConfigurator.Element {
override fun Authentication.Configuration.invoke() {
rolesCheckers.forEach { checker ->

@ -13,59 +13,61 @@ import kotlinx.serialization.builtins.serializer
class UsersRolesStorageReadServerRoutesConfigurator<T : UserRole>(
private val storage: ReadUsersRolesStorage<T>,
private val serializer: KSerializer<T>
private val serializer: KSerializer<T>,
private val unifiedRouter: UnifiedRouter
) : ApplicationRoutingConfigurator.Element {
private val userRolesSerializer = ListSerializer(serializer)
override fun Route.invoke() {
authenticate {
route(usersRolesRootPathPart) {
get(usersRolesGetUsersPathPart) {
val userRole = call.decodeUrlQueryValueOrSendError(usersRolesUserRoleQueryParameterName, serializer)
?: return@get
call.unianswer(
UsersIdsSerializer,
storage.getUsers(userRole)
)
}
get(usersRolesGetRolesPathPart) {
val userId =
call.decodeUrlQueryValueOrSendError(usersRolesUserIdQueryParameterName, UserId.serializer())
unifiedRouter.apply {
authenticate {
route(usersRolesRootPathPart) {
get(usersRolesGetUsersPathPart) {
val userRole = decodeUrlQueryValueOrSendError(usersRolesUserRoleQueryParameterName, serializer)
?: return@get
call.unianswer(
userRolesSerializer,
storage.getRoles(userId)
)
}
unianswer(
UsersIdsSerializer,
storage.getUsers(userRole)
)
}
get(usersRolesContainsPathPart) {
val userId = call.decodeUrlQueryValueOrSendError(
usersRolesUserIdQueryParameterName,
UserId.serializer()
) ?: return@get
val userRole = call.decodeUrlQueryValueOrSendError(
usersRolesUserRoleQueryParameterName,
serializer
) ?: return@get
call.unianswer(
Boolean.serializer(),
storage.contains(userId, userRole)
)
}
get(usersRolesGetRolesPathPart) {
val userId = decodeUrlQueryValueOrSendError(usersRolesUserIdQueryParameterName, UserId.serializer())
?: return@get
unianswer(
userRolesSerializer,
storage.getRoles(userId)
)
}
get(usersRolesContainsAnyPathPart) {
val userId = call.decodeUrlQueryValueOrSendError(
usersRolesUserIdQueryParameterName,
UserId.serializer()
) ?: return@get
val userRoles = call.decodeUrlQueryValueOrSendError(
usersRolesUserRoleQueryParameterName,
userRolesSerializer
) ?: return@get
call.unianswer(
Boolean.serializer(),
storage.containsAny(userId, userRoles)
)
get(usersRolesContainsPathPart) {
val userId = decodeUrlQueryValueOrSendError(
usersRolesUserIdQueryParameterName,
UserId.serializer()
) ?: return@get
val userRole = decodeUrlQueryValueOrSendError(
usersRolesUserRoleQueryParameterName,
serializer
) ?: return@get
unianswer(
Boolean.serializer(),
storage.contains(userId, userRole)
)
}
get(usersRolesContainsAnyPathPart) {
val userId = decodeUrlQueryValueOrSendError(
usersRolesUserIdQueryParameterName,
UserId.serializer()
) ?: return@get
val userRoles = decodeUrlQueryValueOrSendError(
usersRolesUserRoleQueryParameterName,
userRolesSerializer
) ?: return@get
unianswer(
Boolean.serializer(),
storage.containsAny(userId, userRoles)
)
}
}
}
}

@ -13,37 +13,40 @@ class UsersRolesStorageWriteServerRoutesConfigurator<T : UserRole>(
private val storage: WriteUsersRolesStorage<T>,
private val serializer: KSerializer<T>,
private val includeAuthKey: String,
private val excludeAuthKey: String = includeAuthKey
private val excludeAuthKey: String = includeAuthKey,
private val unifiedRouter: UnifiedRouter
) : ApplicationRoutingConfigurator.Element {
override fun Route.invoke() {
route(usersRolesRootPathPart) {
val wrapperSerializer = UserRolesStorageIncludeExcludeWrapper.serializer(
serializer
)
authenticate(includeAuthKey) {
post(usersRolesIncludePathPart) {
val wrapper = call.uniload(wrapperSerializer)
unifiedRouter.apply {
route(usersRolesRootPathPart) {
val wrapperSerializer = UserRolesStorageIncludeExcludeWrapper.serializer(
serializer
)
authenticate(includeAuthKey) {
post(usersRolesIncludePathPart) {
val wrapper = uniload(wrapperSerializer)
call.unianswer(
Boolean.serializer(),
storage.include(
wrapper.userId,
wrapper.userRole
unianswer(
Boolean.serializer(),
storage.include(
wrapper.userId,
wrapper.userRole
)
)
)
}
}
}
authenticate(excludeAuthKey) {
post(usersRolesExcludePathPart) {
val wrapper = call.uniload(wrapperSerializer)
authenticate(excludeAuthKey) {
post(usersRolesExcludePathPart) {
val wrapper = uniload(wrapperSerializer)
call.unianswer(
Boolean.serializer(),
storage.exclude(
wrapper.userId,
wrapper.userRole
unianswer(
Boolean.serializer(),
storage.exclude(
wrapper.userId,
wrapper.userRole
)
)
)
}
}
}
}

@ -1,5 +1,6 @@
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.micro_utils.ktor.server.configurators.ApplicationRoutingConfigurator
import dev.inmo.micro_utils.repos.ktor.server.crud.configureReadStandardCrudRepoRoutes
@ -9,7 +10,8 @@ import io.ktor.routing.route
import kotlinx.serialization.builtins.nullable
class UsersStorageServerRoutesConfigurator(
private val usersStorage: ReadUsersStorage
private val usersStorage: ReadUsersStorage,
private val unifiedRouter: UnifiedRouter
) : ApplicationRoutingConfigurator.Element {
override fun Route.invoke() {
authenticate {
@ -18,7 +20,8 @@ class UsersStorageServerRoutesConfigurator(
usersStorage,
User.serializer(),
User.serializer().nullable,
UserId.serializer()
UserId.serializer(),
unifiedRouter
)
}
}

@ -18,6 +18,7 @@ dependencies {
api project(":postssystem.features.auth.server")
api project(":postssystem.features.roles.server")
api project(":postssystem.features.roles.manager.server")
api project(":postssystem.features.content.server")
api "io.ktor:ktor-server-netty:$ktor_version"
api "io.ktor:ktor-websockets:$ktor_version"
api "org.jetbrains.exposed:exposed-jdbc:$kotlin_exposed_version"

@ -3,8 +3,6 @@ package dev.inmo.postssystem.server
import dev.inmo.postssystem.features.auth.server.AuthenticationRoutingConfigurator
import dev.inmo.postssystem.features.auth.server.SessionAuthenticationConfigurator
import dev.inmo.postssystem.features.auth.server.tokens.*
import dev.inmo.postssystem.features.common.common.getAllDistinct
import dev.inmo.postssystem.features.common.common.singleWithBinds
import dev.inmo.postssystem.features.common.server.sessions.ApplicationAuthenticationConfigurator
import dev.inmo.postssystem.features.files.common.*
import dev.inmo.postssystem.features.files.common.storage.*
@ -21,10 +19,15 @@ import dev.inmo.postssystem.features.status.server.StatusRoutingConfigurator
import dev.inmo.postssystem.features.users.common.ExposedUsersStorage
import dev.inmo.postssystem.features.users.server.UsersStorageServerRoutesConfigurator
import dev.inmo.micro_utils.coroutines.LinkedSupervisorScope
import dev.inmo.micro_utils.ktor.common.standardKtorSerialFormat
import dev.inmo.micro_utils.ktor.server.UnifiedRouter
import dev.inmo.micro_utils.ktor.server.configurators.*
import dev.inmo.micro_utils.ktor.server.createKtorServer
import dev.inmo.micro_utils.repos.exposed.keyvalue.ExposedKeyValueRepo
import dev.inmo.micro_utils.repos.exposed.onetomany.ExposedOneToManyKeyValueRepo
import dev.inmo.postssystem.features.common.common.*
import dev.inmo.postssystem.features.content.common.ContentSerializersModuleConfigurator
import dev.inmo.postssystem.features.content.common.OtherContentSerializerModuleConfigurator
import io.ktor.application.featureOrNull
import io.ktor.application.log
import io.ktor.routing.Route
@ -33,8 +36,11 @@ import io.ktor.server.engine.ApplicationEngine
import io.ktor.server.netty.Netty
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.serialization.BinaryFormat
import kotlinx.serialization.StringFormat
import kotlinx.serialization.cbor.Cbor
import kotlinx.serialization.json.Json
import kotlinx.serialization.modules.SerializersModule
import org.jetbrains.exposed.sql.Database
import org.koin.core.module.Module
import org.koin.core.parameter.ParametersHolder
@ -54,21 +60,36 @@ fun getDIModule(
vararg args: String,
baseScope: CoroutineScope = CoroutineScope(Dispatchers.IO)
): Module {
val json = Json {
val configJson = Json {
ignoreUnknownKeys = true
}
val config = json.decodeFromString(Config.serializer(), File(args.first()).readText())
val config = configJson.decodeFromString(Config.serializer(), File(args.first()).readText())
val originalFilesMetasKeyValueRepoQualifier = StringQualifier("OriginalFilesMetaKV")
val filesMetasKeyValueRepoQualifier = StringQualifier("FilesMetaKV")
val filesFolderQualifier = StringQualifier("filesFolder")
val reviewVersionsQualifier = StringQualifier("reviewVersions")
val releaseVersionsQualifier = StringQualifier("releaseVersions")
val usersRolesKeyValueFactoryQualifier = StringQualifier("usersRolesKeyValueFactory")
return module {
single { json }
singleWithRandomQualifier<ContentSerializersModuleConfigurator.Element> { OtherContentSerializerModuleConfigurator }
singleWithRandomQualifier<SerializersModuleConfigurator.Element> { ContentSerializersModuleConfigurator(getAll()) }
single { SerializersModuleConfigurator(getAll()) }
single {
Json {
ignoreUnknownKeys = true
serializersModule = SerializersModule { get<SerializersModuleConfigurator>().apply { invoke() } }
}
}
single<StringFormat> { get<Json>() }
single<BinaryFormat> {
Cbor {
serializersModule = SerializersModule { get<SerializersModuleConfigurator>().apply { invoke() } }
}
}
single { UnifiedRouter(get()) }
singleWithBinds { config }
singleWithBinds { get<Config>().databaseConfig }
singleWithBinds { get<Config>().authConfig }
@ -111,11 +132,11 @@ fun getDIModule(
factory<CoroutineScope> { baseScope.LinkedSupervisorScope() }
// Routing configurators
singleWithBinds { FilesRoutingConfigurator(get(), null) }
singleWithBinds { FilesRoutingConfigurator(get(), null, get()) }
singleWithBinds { StatusRoutingConfigurator }
singleWithBinds { UsersStorageServerRoutesConfigurator(get()) }
singleWithBinds { UsersRolesStorageReadServerRoutesConfigurator<UserRole>(get(), UserRoleSerializer) }
singleWithBinds { RolesManagerUsersRolesStorageServerRoutesConfigurator(get()) }
singleWithBinds { UsersStorageServerRoutesConfigurator(get(), get()) }
singleWithBinds { UsersRolesStorageReadServerRoutesConfigurator<UserRole>(get(), UserRoleSerializer, get()) }
singleWithBinds { RolesManagerUsersRolesStorageServerRoutesConfigurator(get(), get()) }
singleWithBinds { ClientStaticRoutingConfiguration(get<Config>().clientStatic) }
singleWithBinds {
@ -137,7 +158,7 @@ fun getDIModule(
get()
)
}
singleWithBinds { AuthenticationRoutingConfigurator(get(), get()) }
singleWithBinds { AuthenticationRoutingConfigurator(get(), get(), get()) }
if (config.debugMode) {
single<ApplicationRoutingConfigurator.Element>(StringQualifier("Tracer")) { ApplicationRoutingConfigurator.Element {(this as Routing).trace { application.log.trace(it.buildText()) } } }

@ -29,6 +29,10 @@ String[] includes = [
":features:auth:client",
":features:auth:server",
":features:content:common",
":features:content:client",
":features:content:server",
":server",
":client",
]