add content

This commit is contained in:
InsanusMokrassar 2021-11-24 20:25:05 +06:00
parent fffe99adaa
commit 58b7e973be
24 changed files with 398 additions and 176 deletions

View File

@ -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"

View File

@ -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()) }

View File

@ -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())
)
)
}
}
}

View File

@ -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)

View File

@ -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)

View File

@ -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() } }
}
}

View File

@ -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)
}

View File

@ -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")
}
}
}
}

View File

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

View File

@ -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")
}
}
}
}

View File

@ -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
)

View File

@ -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() } }
}
}
}

View File

@ -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())
}
}

View File

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

View File

@ -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")
}
}
}
}

View File

@ -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
)
)
)
}
}
}
}

View File

@ -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
)

View File

@ -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 ->

View File

@ -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)
)
}
}
}
}

View File

@ -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
)
)
)
}
}
}
}

View File

@ -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
)
}
}

View File

@ -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"

View File

@ -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()) } } }

View File

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