full reborn
This commit is contained in:
18
features/roles/common/build.gradle
Normal file
18
features/roles/common/build.gradle
Normal 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.common.common")
|
||||
api project(":postssystem.features.users.common")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,26 @@
|
||||
package dev.inmo.postssystem.features.roles.common
|
||||
|
||||
import dev.inmo.postssystem.features.users.common.UserId
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.builtins.ListSerializer
|
||||
|
||||
const val usersRolesRootPathPart = "roles"
|
||||
|
||||
val UsersIdsSerializer = ListSerializer(UserId.serializer())
|
||||
|
||||
const val usersRolesUserRoleQueryParameterName = "userRole"
|
||||
const val usersRolesUserIdQueryParameterName = "userId"
|
||||
|
||||
const val usersRolesGetUsersPathPart = "getUsersByRole"
|
||||
const val usersRolesGetRolesPathPart = "getUserRoles"
|
||||
const val usersRolesContainsPathPart = "contains"
|
||||
const val usersRolesContainsAnyPathPart = "containsAny"
|
||||
|
||||
const val usersRolesIncludePathPart = "include"
|
||||
const val usersRolesExcludePathPart = "exclude"
|
||||
|
||||
@Serializable
|
||||
data class UserRolesStorageIncludeExcludeWrapper<T : UserRole>(
|
||||
val userId: UserId,
|
||||
val userRole: T
|
||||
)
|
@@ -0,0 +1,81 @@
|
||||
package dev.inmo.postssystem.features.roles.common
|
||||
|
||||
import kotlinx.serialization.*
|
||||
import kotlinx.serialization.builtins.serializer
|
||||
import kotlinx.serialization.descriptors.SerialDescriptor
|
||||
import kotlinx.serialization.encoding.*
|
||||
import kotlinx.serialization.json.*
|
||||
|
||||
@Serializable(UserRoleSerializer::class)
|
||||
interface UserRole { // temporarily made as class while interfaces are bugged
|
||||
companion object {
|
||||
fun serializer() = UserRoleSerializer
|
||||
}
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class UnknownUserRole(val originalJson: JsonElement) : UserRole
|
||||
|
||||
@Serializer(UserRole::class)
|
||||
object UserRoleSerializer : KSerializer<UserRole> {
|
||||
private val userRoleFormat = Json { ignoreUnknownKeys = true }
|
||||
private const val keyField = "key"
|
||||
private const val valueField = "value"
|
||||
private val serializers = mutableMapOf<String, KSerializer<out UserRole>>()
|
||||
override val descriptor: SerialDescriptor = String.serializer().descriptor
|
||||
|
||||
@InternalSerializationApi
|
||||
override fun deserialize(decoder: Decoder): UserRole {
|
||||
return if (decoder is JsonDecoder) {
|
||||
val originalJson = decoder.decodeJsonElement().jsonObject
|
||||
val type = originalJson[keyField]?.jsonPrimitive ?.content
|
||||
return if (type == null || !serializers.containsKey(type)) {
|
||||
UnknownUserRole(originalJson)
|
||||
} else {
|
||||
userRoleFormat.decodeFromJsonElement(
|
||||
serializers.getValue(type),
|
||||
originalJson[valueField] ?: buildJsonObject { }
|
||||
)
|
||||
}
|
||||
} else {
|
||||
val encoded = decoder.decodeString()
|
||||
userRoleFormat.decodeFromString(this, encoded)
|
||||
}
|
||||
}
|
||||
|
||||
@InternalSerializationApi
|
||||
private fun <T : UserRole> T.toJson(): JsonElement {
|
||||
return userRoleFormat.encodeToJsonElement(this::class.serializer() as KSerializer<T>, this)
|
||||
}
|
||||
|
||||
@InternalSerializationApi
|
||||
override fun serialize(encoder: Encoder, value: UserRole) {
|
||||
if (encoder is JsonEncoder) {
|
||||
if (value is UnknownUserRole) {
|
||||
encoder.encodeJsonElement(value.originalJson)
|
||||
} else {
|
||||
val valueSerializer = value::class.serializer()
|
||||
val type = serializers.keys.first { serializers[it] == valueSerializer }
|
||||
encoder.encodeJsonElement(
|
||||
buildJsonObject {
|
||||
put(keyField, type)
|
||||
put(valueField, value.toJson())
|
||||
}
|
||||
)
|
||||
}
|
||||
} else {
|
||||
encoder.encodeString(
|
||||
userRoleFormat.encodeToString(this, value)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun <T : UserRole> includeSerializer(
|
||||
type: String,
|
||||
kSerializer: KSerializer<T>
|
||||
) { serializers[type] = kSerializer }
|
||||
|
||||
fun excludeSerializer(type: String) {
|
||||
serializers.remove(type)
|
||||
}
|
||||
}
|
@@ -0,0 +1,5 @@
|
||||
package dev.inmo.postssystem.features.roles.common
|
||||
|
||||
import kotlinx.serialization.builtins.ListSerializer
|
||||
|
||||
val UserRolesSerializer = ListSerializer(UserRole.serializer())
|
@@ -0,0 +1,16 @@
|
||||
package dev.inmo.postssystem.features.roles.common
|
||||
|
||||
import dev.inmo.postssystem.features.users.common.UserId
|
||||
|
||||
interface ReadUsersRolesStorage<T : UserRole> {
|
||||
suspend fun getUsers(userRole: T): List<UserId>
|
||||
suspend fun getRoles(userId: UserId): List<T>
|
||||
suspend fun contains(userId: UserId, userRole: T): Boolean
|
||||
suspend fun containsAny(userId: UserId, userRoles: List<T>): Boolean
|
||||
}
|
||||
interface WriteUsersRolesStorage<T : UserRole> {
|
||||
suspend fun include(userId: UserId, userRole: T): Boolean
|
||||
suspend fun exclude(userId: UserId, userRole: T): Boolean
|
||||
}
|
||||
|
||||
interface UsersRolesStorage<T : UserRole> : ReadUsersRolesStorage<T>, WriteUsersRolesStorage<T>
|
@@ -0,0 +1,5 @@
|
||||
package dev.inmo.postssystem.features.roles.common.keyvalue
|
||||
|
||||
import dev.inmo.micro_utils.repos.KeyValuesRepo
|
||||
|
||||
typealias KeyValuesUsersRolesOriginalRepo = KeyValuesRepo<Long, String>
|
@@ -0,0 +1,13 @@
|
||||
package dev.inmo.postssystem.features.roles.common.keyvalue
|
||||
|
||||
import dev.inmo.postssystem.features.roles.common.*
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.StringFormat
|
||||
|
||||
open class KeyValueUsersRolesStorage<T : UserRole>(
|
||||
private val keyValuesRepo: KeyValuesUsersRolesOriginalRepo,
|
||||
private val serializer: KSerializer<T>,
|
||||
private val format: StringFormat = ReadKeyValueUsersRolesStorage.defaultJson
|
||||
) : UsersRolesStorage<T>,
|
||||
ReadUsersRolesStorage<T> by ReadKeyValueUsersRolesStorage(keyValuesRepo, serializer, format),
|
||||
WriteUsersRolesStorage<T> by WriteKeyValueUsersRolesStorage(keyValuesRepo, serializer, format)
|
@@ -0,0 +1,59 @@
|
||||
package dev.inmo.postssystem.features.roles.common.keyvalue
|
||||
|
||||
import dev.inmo.postssystem.features.common.common.default
|
||||
import dev.inmo.postssystem.features.roles.common.ReadUsersRolesStorage
|
||||
import dev.inmo.postssystem.features.roles.common.UserRole
|
||||
import dev.inmo.postssystem.features.users.common.UserId
|
||||
import dev.inmo.micro_utils.pagination.changeResults
|
||||
import dev.inmo.micro_utils.pagination.utils.getAllByWithNextPaging
|
||||
import dev.inmo.micro_utils.repos.ReadKeyValuesRepo
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.StringFormat
|
||||
import kotlinx.serialization.json.Json
|
||||
|
||||
open class ReadKeyValueUsersRolesStorage<T : UserRole>(
|
||||
private val keyValuesRepo: ReadKeyValuesRepo<Long, String>,
|
||||
private val serializer: KSerializer<T>,
|
||||
private val format: StringFormat = defaultJson
|
||||
) : ReadUsersRolesStorage<T> {
|
||||
override suspend fun getUsers(userRole: T): List<UserId> {
|
||||
val serialized = format.encodeToString(serializer, userRole)
|
||||
|
||||
return keyValuesRepo.getAllByWithNextPaging {
|
||||
keys(serialized, it).let { paginationResult ->
|
||||
paginationResult.changeResults(
|
||||
paginationResult.results.map { UserId(it) }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getRoles(userId: UserId): List<T> {
|
||||
return keyValuesRepo.getAllByWithNextPaging {
|
||||
get(userId.long, it).let { paginationResult ->
|
||||
paginationResult.changeResults(
|
||||
paginationResult.results.map { serialized ->
|
||||
format.decodeFromString(serializer, serialized)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun contains(userId: UserId, userRole: T): Boolean {
|
||||
val serialized = format.encodeToString(serializer, userRole)
|
||||
|
||||
return keyValuesRepo.contains(userId.long, serialized)
|
||||
}
|
||||
|
||||
override suspend fun containsAny(userId: UserId, userRoles: List<T>): Boolean {
|
||||
return userRoles.any {
|
||||
contains(userId, it)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
internal val defaultJson = Json.default
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,34 @@
|
||||
package dev.inmo.postssystem.features.roles.common.keyvalue
|
||||
|
||||
import dev.inmo.postssystem.features.roles.common.UserRole
|
||||
import dev.inmo.postssystem.features.roles.common.WriteUsersRolesStorage
|
||||
import dev.inmo.postssystem.features.users.common.UserId
|
||||
import dev.inmo.micro_utils.repos.*
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.StringFormat
|
||||
|
||||
open class WriteKeyValueUsersRolesStorage<T : UserRole>(
|
||||
private val keyValuesRepo: WriteKeyValuesRepo<Long, String>,
|
||||
private val serializer: KSerializer<T>,
|
||||
private val format: StringFormat = ReadKeyValueUsersRolesStorage.defaultJson
|
||||
) : WriteUsersRolesStorage<T> {
|
||||
override suspend fun include(userId: UserId, userRole: T): Boolean {
|
||||
return runCatching {
|
||||
keyValuesRepo.add(
|
||||
userId.long,
|
||||
format.encodeToString(serializer, userRole)
|
||||
)
|
||||
true
|
||||
}.getOrElse { false }
|
||||
}
|
||||
|
||||
override suspend fun exclude(userId: UserId, userRole: T): Boolean {
|
||||
return runCatching {
|
||||
keyValuesRepo.remove(
|
||||
userId.long,
|
||||
format.encodeToString(serializer, userRole)
|
||||
)
|
||||
true
|
||||
}.getOrElse { false }
|
||||
}
|
||||
}
|
1
features/roles/common/src/main/AndroidManifest.xml
Normal file
1
features/roles/common/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1 @@
|
||||
<manifest package="dev.inmo.postssystem.features.roles.common"/>
|
Reference in New Issue
Block a user