start second (or third?) reborn
This commit is contained in:
@@ -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 {
|
||||
|
@@ -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
|
||||
|
@@ -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") {
|
||||
|
@@ -1 +0,0 @@
|
||||
<manifest package="dev.inmo.postssystem.features.auth.client"/>
|
@@ -1 +0,0 @@
|
||||
<manifest package="dev.inmo.postssystem.features.auth.common"/>
|
@@ -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
|
||||
|
@@ -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.*
|
||||
|
@@ -1 +0,0 @@
|
||||
<manifest package="dev.inmo.postssystem.features.client.template.client"/>
|
@@ -1 +0,0 @@
|
||||
<manifest package="dev.inmo.postssystem.features.client.template.common"/>
|
@@ -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 {
|
||||
|
@@ -1 +0,0 @@
|
||||
<manifest package="dev.inmo.postssystem.features.common.client"/>
|
@@ -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
|
||||
|
@@ -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())
|
||||
}
|
||||
|
@@ -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)
|
||||
}
|
@@ -1 +0,0 @@
|
||||
<manifest package="dev.inmo.postssystem.features.common.common"/>
|
@@ -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)
|
||||
}
|
@@ -1 +0,0 @@
|
||||
<manifest package="dev.inmo.postssystem.features.content.binary.client"/>
|
@@ -1 +0,0 @@
|
||||
<manifest package="dev.inmo.postssystem.features.content.binary.common"/>
|
@@ -1 +0,0 @@
|
||||
<manifest package="dev.inmo.postssystem.features.content.client"/>
|
@@ -1 +0,0 @@
|
||||
<manifest package="dev.inmo.postssystem.features.content.common"/>
|
@@ -1 +0,0 @@
|
||||
<manifest package="dev.inmo.postssystem.features.content.content.text.client"/>
|
@@ -1 +0,0 @@
|
||||
<manifest package="dev.inmo.postssystem.features.content.content.text.common"/>
|
@@ -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()
|
||||
}
|
||||
|
@@ -1 +0,0 @@
|
||||
<manifest package="dev.inmo.postssystem.features.files.client"/>
|
@@ -61,4 +61,8 @@ class DiskReadFilesStorage(
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun getIdsByPagination(pagination: Pagination): PaginationResult<FileId> {
|
||||
return metasKeyValueRepo.keys(pagination)
|
||||
}
|
||||
}
|
||||
|
@@ -1 +0,0 @@
|
||||
<manifest package="dev.inmo.postssystem.features.files.common"/>
|
@@ -1 +0,0 @@
|
||||
<manifest package="dev.inmo.postssystem.features.posts.client"/>
|
@@ -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
|
||||
|
@@ -1 +0,0 @@
|
||||
<manifest package="dev.inmo.postssystem.features.posts.common"/>
|
@@ -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.*
|
||||
|
@@ -1 +0,0 @@
|
||||
<manifest package="dev.inmo.postssystem.features.publication.client"/>
|
@@ -1 +0,0 @@
|
||||
<manifest package="dev.inmo.postssystem.features.publication.common"/>
|
@@ -1 +0,0 @@
|
||||
<manifest package="dev.inmo.postssystem.features.roles.client"/>
|
@@ -1 +0,0 @@
|
||||
<manifest package="dev.inmo.postssystem.features.roles.common"/>
|
@@ -1 +0,0 @@
|
||||
<manifest package="dev.inmo.postssystem.features.roles.manager.client"/>
|
@@ -1 +0,0 @@
|
||||
<manifest package="dev.inmo.postssystem.features.roles.manager.common"/>
|
@@ -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(
|
||||
|
@@ -1 +0,0 @@
|
||||
<manifest package="dev.inmo.postssystem.features.status.client"/>
|
@@ -1 +0,0 @@
|
||||
<manifest package="dev.inmo.postssystem.features.status.common"/>
|
@@ -1 +0,0 @@
|
||||
<manifest package="dev.inmo.postssystem.features.template.client"/>
|
@@ -1 +0,0 @@
|
||||
<manifest package="dev.inmo.postssystem.features.template.common"/>
|
@@ -1 +0,0 @@
|
||||
<manifest package="dev.inmo.postssystem.features.users.client"/>
|
@@ -21,7 +21,3 @@ kotlin {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
android {
|
||||
disableIncludingJvmCodeInAndroidPart()
|
||||
}
|
||||
|
@@ -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,
|
||||
|
@@ -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),
|
||||
|
@@ -1 +0,0 @@
|
||||
<manifest package="dev.inmo.postssystem.features.users.common"/>
|
Reference in New Issue
Block a user