start second (or third?) reborn

This commit is contained in:
2024-02-16 13:40:47 +06:00
parent ff973e63fc
commit e98a484c4d
72 changed files with 173 additions and 200 deletions

View File

@@ -1,7 +1,6 @@
package dev.inmo.postssystem.features.auth.client
import dev.inmo.micro_utils.common.Either
import dev.inmo.micro_utils.ktor.client.UnifiedRequester
import dev.inmo.postssystem.features.auth.common.AuthKey
import dev.inmo.postssystem.features.auth.common.AuthTokenInfo
import dev.inmo.postssystem.features.common.common.AdditionalModules
@@ -27,7 +26,6 @@ fun createAuthorizedFeaturesDIModule(
installClientAuthenticator(serverUrl, get(), get(AuthorizedQualifiers.CredsQualifier), onAuthKeyUpdated, onUserRetrieved, onAuthKeyInvalidated)
}
}
single { UnifiedRequester(get(), get()) }
single { StatusFeatureClient(get(AuthorizedQualifiers.ServerUrlQualifier), get()) }
AdditionalModules.Authorized.modules.forEach {

View File

@@ -2,14 +2,14 @@ package dev.inmo.postssystem.features.auth.client
import dev.inmo.postssystem.features.auth.common.*
import dev.inmo.postssystem.features.users.common.User
import dev.inmo.micro_utils.ktor.client.UnifiedRequester
import dev.inmo.micro_utils.ktor.client.bodyOrNull
import dev.inmo.micro_utils.ktor.common.buildStandardUrl
import io.ktor.client.HttpClient
import io.ktor.client.request.HttpRequestBuilder
import io.ktor.client.request.*
import kotlinx.serialization.builtins.nullable
class ClientAuthFeature(
private val requester: UnifiedRequester,
private val client: HttpClient,
baseUrl: String
) : AuthFeature {
private val rootUrl = buildStandardUrl(baseUrl.dropLastWhile { it == '/' }, authRootPathPart)
@@ -26,28 +26,23 @@ class ClientAuthFeature(
authGetMePathPart
)
constructor(client: HttpClient, rootUrl: String): this(
UnifiedRequester(client),
rootUrl
)
override suspend fun auth(creds: AuthCreds): AuthTokenInfo? = client.post(
fullAuthPath
) {
setBody(creds)
}.bodyOrNull()
override suspend fun auth(creds: AuthCreds): AuthTokenInfo? = requester.unipost(
fullAuthPath,
AuthCreds.serializer() to creds,
AuthTokenInfo.serializer().nullable
)
override suspend fun refresh(refresh: RefreshToken): AuthTokenInfo? = client.post(
fullRefreshPath
) {
setBody(refresh)
}.bodyOrNull()
override suspend fun refresh(refresh: RefreshToken): AuthTokenInfo? = requester.unipost(
fullRefreshPath,
RefreshToken.serializer() to refresh,
AuthTokenInfo.serializer().nullable
)
override suspend fun getMe(authToken: AuthToken): User? = requester.unipost(
fullGetMePath,
AuthToken.serializer() to authToken,
User.serializer().nullable
)
override suspend fun getMe(authToken: AuthToken): User? = client.post(
fullGetMePath
) {
setBody(authToken)
}.bodyOrNull()
fun isAuthRequest(builder: HttpRequestBuilder): Boolean = builder.url.buildString().let {
it == fullAuthPath || it == fullRefreshPath

View File

@@ -37,7 +37,7 @@ fun HttpClientConfig<*>.installClientAuthenticator(
}.onSecond {
currentRefreshToken = it.refresh
}
val creds = initialAuthKey.t1 as? AuthCreds
val creds = initialAuthKey.t1OrNull as? AuthCreds
var userRefreshJob: Job? = null
install("Auth Token Refresher") {

View File

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

View File

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

View File

@@ -1,6 +1,6 @@
package dev.inmo.postssystem.features.auth.server.tokens
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
import dev.inmo.postssystem.features.auth.common.AuthToken
import dev.inmo.postssystem.features.auth.common.RefreshToken
import dev.inmo.postssystem.features.users.common.UserId

View File

@@ -1,7 +1,7 @@
package dev.inmo.postssystem.features.auth.server.tokens
import com.soywiz.klock.DateTime
import com.soywiz.klock.milliseconds
import korlibs.time.DateTime
import korlibs.time.milliseconds
import dev.inmo.postssystem.features.auth.common.*
import dev.inmo.postssystem.features.common.common.Milliseconds
import dev.inmo.postssystem.features.users.common.*

View File

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

View File

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

View File

@@ -1,8 +1,8 @@
package dev.inmo.postssystem.features.common.common.ui
import androidx.compose.runtime.Composable
import com.soywiz.klock.DateTime
import com.soywiz.klock.ISO8601
import korlibs.time.DateTime
import korlibs.time.ISO8601
import org.jetbrains.compose.web.dom.Text
object DateTimeView {

View File

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

View File

@@ -1,6 +1,6 @@
package dev.inmo.postssystem.features.common.common
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializer
import kotlinx.serialization.builtins.serializer

View File

@@ -1,6 +1,7 @@
package dev.inmo.postssystem.features.common.common
import org.koin.core.definition.Definition
import org.koin.core.definition.KoinDefinition
import org.koin.core.instance.InstanceFactory
import org.koin.core.module.Module
import org.koin.core.qualifier.Qualifier
@@ -11,6 +12,6 @@ inline fun <reified T : Any> Module.singleWithBinds(
qualifier: Qualifier? = null,
createdAtStart: Boolean = false,
noinline definition: Definition<T>
): Pair<Module, InstanceFactory<*>> {
): KoinDefinition<*> {
return single(qualifier, createdAtStart, definition) binds (T::class.allSuperclasses.toTypedArray())
}

View File

@@ -0,0 +1,10 @@
package dev.inmo.postssystem.features.common.common
import dev.inmo.micro_utils.common.MPPFile
import dev.inmo.micro_utils.common.filename
import dev.inmo.micro_utils.mime_types.*
actual val MPPFile.mimeType: MimeType
get() {
return getMimeTypeOrAny(filename.extension)
}

View File

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

View File

@@ -0,0 +1,11 @@
package dev.inmo.postssystem.features.common.common
import dev.inmo.micro_utils.common.MPPFile
import dev.inmo.micro_utils.common.filename
import dev.inmo.micro_utils.mime_types.MimeType
import dev.inmo.micro_utils.mime_types.getMimeTypeOrAny
actual val MPPFile.mimeType: MimeType
get() {
return getMimeTypeOrAny(filename.extension)
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -2,28 +2,28 @@ package dev.inmo.postssystem.features.files.client
import dev.inmo.postssystem.features.files.common.*
import dev.inmo.postssystem.features.files.common.storage.ReadFilesStorage
import dev.inmo.micro_utils.ktor.client.UnifiedRequester
import dev.inmo.micro_utils.ktor.client.bodyOrNull
import dev.inmo.micro_utils.ktor.common.buildStandardUrl
import dev.inmo.micro_utils.repos.ReadCRUDRepo
import dev.inmo.micro_utils.repos.ktor.client.crud.KtorReadStandardCrudRepo
import dev.inmo.micro_utils.repos.ktor.client.crud.KtorReadCRUDRepoClient
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.request.*
import io.ktor.client.statement.readBytes
import io.ktor.http.ContentType
import io.ktor.http.encodeURLQueryComponent
import kotlinx.serialization.BinaryFormat
import kotlinx.serialization.builtins.nullable
class ClientReadFilesStorage(
baseUrl: String,
private val client: HttpClient,
private val serialFormat: BinaryFormat
) : ReadFilesStorage, ReadCRUDRepo<MetaFileInfoStorageWrapper, FileId> by KtorReadStandardCrudRepo(
private val serialFormat: BinaryFormat,
contentType: ContentType
) : ReadFilesStorage, ReadCRUDRepo<MetaFileInfoStorageWrapper, FileId> by KtorReadCRUDRepoClient<MetaFileInfoStorageWrapper, FileId>(
buildStandardUrl(baseUrl, filesRootPathPart),
UnifiedRequester(client, serialFormat),
MetaFileInfoStorageWrapper.serializer(),
MetaFileInfoStorageWrapper.serializer().nullable,
FileId.serializer()
client,
contentType,
{ it.string.encodeURLQueryComponent() }
) {
private val fullFilesPath = buildStandardUrl(baseUrl, filesRootPathPart)
private val fullFilesGetBytesPath = buildStandardUrl(
@@ -37,12 +37,11 @@ class ClientReadFilesStorage(
override suspend fun getFullFileInfo(
id: FileId
): FullFileInfoStorageWrapper? = unifiedRequester.uniget(
): FullFileInfoStorageWrapper? = client.get(
buildStandardUrl(
fullFilesPath,
filesGetFullFileInfoPathPart,
filesFileIdParameter to unifiedRequester.encodeUrlQueryValue(FileId.serializer(), id)
),
FullFileInfoStorageWrapper.serializer().nullable
)
filesFileIdParameter to id.string.encodeURLQueryComponent()
)
).bodyOrNull()
}

View File

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

View File

@@ -61,4 +61,8 @@ class DiskReadFilesStorage(
}
)
}
override suspend fun getIdsByPagination(pagination: Pagination): PaginationResult<FileId> {
return metasKeyValueRepo.keys(pagination)
}
}

View File

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

View File

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

View File

@@ -1,6 +1,6 @@
package dev.inmo.postssystem.features.posts.common
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
import dev.inmo.postssystem.features.common.common.DateTimeSerializer
import dev.inmo.postssystem.features.content.common.Content
import dev.inmo.postssystem.features.content.common.ContentId

View File

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

View File

@@ -1,6 +1,6 @@
package dev.inmo.postssystem.features.posts.server
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
import dev.inmo.micro_utils.repos.exposed.*
import dev.inmo.postssystem.features.content.common.ContentId
import dev.inmo.postssystem.features.posts.common.*

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -2,11 +2,9 @@ package dev.inmo.postssystem.features.status.client
import dev.inmo.postssystem.features.status.common.statusAuthorisedPathPart
import dev.inmo.postssystem.features.status.common.statusRootPart
import dev.inmo.micro_utils.ktor.client.UnifiedRequester
import dev.inmo.micro_utils.ktor.common.buildStandardUrl
import io.ktor.client.HttpClient
import io.ktor.client.request.get
import io.ktor.client.statement.HttpResponse
import io.ktor.http.HttpStatusCode
class StatusFeatureClient(

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -21,7 +21,3 @@ kotlin {
}
}
}
android {
disableIncludingJvmCodeInAndroidPart()
}

View File

@@ -31,7 +31,7 @@ sealed class User : NewUser {
}
@Serializable
data class DefaultUser(
data class RegisteredUser(
override val id: UserId,
override val firstName: String,
override val lastName: String,

View File

@@ -3,8 +3,7 @@ package dev.inmo.postssystem.features.users.common
import dev.inmo.micro_utils.repos.exposed.AbstractExposedCRUDRepo
import dev.inmo.micro_utils.repos.exposed.initTable
import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.statements.InsertStatement
import org.jetbrains.exposed.sql.statements.UpdateStatement
import org.jetbrains.exposed.sql.statements.*
class ExposedUsersStorage(override val database: Database) : UsersStorage, AbstractExposedCRUDRepo<User, UserId, NewUser>(
tableName = "Users"
@@ -15,11 +14,12 @@ class ExposedUsersStorage(override val database: Database) : UsersStorage, Abstr
private val lastNameColumn = text("lastName")
override val primaryKey: PrimaryKey = PrimaryKey(userIdColumn)
override val selectById: ISqlExpressionBuilder.(UserId) -> Op<Boolean> = { userIdColumn.eq(it.long) }
override val ResultRow.asId: UserId
get() = UserId(get(userIdColumn))
override val selectByIds: SqlExpressionBuilder.(List<UserId>) -> Op<Boolean> = { userIdColumn.inList(it.map { it.long }) }
override val selectById: SqlExpressionBuilder.(UserId) -> Op<Boolean> = { userIdColumn.eq(it.long) }
override val ResultRow.asObject: User
get() = DefaultUser(
get() = RegisteredUser(
get(userIdColumn).userId,
get(firstNameColumn),
get(lastNameColumn),
@@ -36,13 +36,13 @@ class ExposedUsersStorage(override val database: Database) : UsersStorage, Abstr
it[lastNameColumn] = value.lastName
}
override fun update(id: UserId, value: NewUser, it: UpdateStatement) {
override fun update(id: UserId?, value: NewUser, it: UpdateBuilder<Int>) {
it[usernameColumn] = value.username.string
it[firstNameColumn] = value.firstName
it[lastNameColumn] = value.lastName
}
override fun InsertStatement<Number>.asObject(value: NewUser): User = DefaultUser(
override fun InsertStatement<Number>.asObject(value: NewUser): User = RegisteredUser(
get(userIdColumn).userId,
get(firstNameColumn),
get(lastNameColumn),

View File

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