roles update and gradle scripts fixes
This commit is contained in:
client/src/commonMain/kotlin/dev/inmo/postssystem/client
features/roles
client
src
commonMain
kotlin
dev
inmo
postssystem
common
src
commonMain
kotlin
dev
inmo
manager
common
src
commonMain
kotlin
dev
inmo
postssystem
features
roles
manager
server
src
jvmMain
kotlin
dev
inmo
postssystem
features
server
src
jvmMain
server/src/main/java/dev/inmo/postssystem/server
14
features/roles/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/common/Constants.kt
14
features/roles/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/common/Constants.kt
@ -6,13 +6,13 @@ import kotlinx.serialization.builtins.ListSerializer
|
||||
|
||||
const val usersRolesRootPathPart = "roles"
|
||||
|
||||
val UsersIdsSerializer = ListSerializer(UserId.serializer())
|
||||
val RoleSubjectsSerializer = ListSerializer(RoleSubject.serializer())
|
||||
|
||||
const val usersRolesUserRoleQueryParameterName = "userRole"
|
||||
const val usersRolesUserIdQueryParameterName = "userId"
|
||||
const val usersRolesRoleQueryParameterName = "userRole"
|
||||
const val usersRolesRoleSubjectQueryParameterName = "subject"
|
||||
|
||||
const val usersRolesGetUsersPathPart = "getUsersByRole"
|
||||
const val usersRolesGetRolesPathPart = "getUserRoles"
|
||||
const val usersRolesGetSubjectsPathPart = "getSubjectsByRole"
|
||||
const val usersRolesGetRolesPathPart = "getSubjectRoles"
|
||||
const val usersRolesContainsPathPart = "contains"
|
||||
const val usersRolesContainsAnyPathPart = "containsAny"
|
||||
|
||||
@ -20,7 +20,7 @@ const val usersRolesIncludePathPart = "include"
|
||||
const val usersRolesExcludePathPart = "exclude"
|
||||
|
||||
@Serializable
|
||||
data class UserRolesStorageIncludeExcludeWrapper<T : UserRole>(
|
||||
val userId: UserId,
|
||||
data class RolesStorageIncludeExcludeWrapper<T : Role>(
|
||||
val subject: RoleSubject,
|
||||
val userRole: T
|
||||
)
|
||||
|
@ -6,31 +6,31 @@ 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
|
||||
@Serializable(RoleSerializer::class)
|
||||
interface Role {
|
||||
companion object {
|
||||
fun serializer() = UserRoleSerializer
|
||||
fun serializer() = RoleSerializer
|
||||
}
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class UnknownUserRole(val originalJson: JsonElement) : UserRole
|
||||
data class UnknownRole(val originalJson: JsonElement) : Role
|
||||
|
||||
@Serializer(UserRole::class)
|
||||
object UserRoleSerializer : KSerializer<UserRole> {
|
||||
@Serializer(Role::class)
|
||||
object RoleSerializer : KSerializer<Role> {
|
||||
private val userRoleFormat = Json { ignoreUnknownKeys = true }
|
||||
private const val keyField = "key"
|
||||
private const val valueField = "value"
|
||||
private val serializers = mutableMapOf<String, KSerializer<out UserRole>>()
|
||||
private val serializers = mutableMapOf<String, KSerializer<out Role>>()
|
||||
override val descriptor: SerialDescriptor = String.serializer().descriptor
|
||||
|
||||
@InternalSerializationApi
|
||||
override fun deserialize(decoder: Decoder): UserRole {
|
||||
override fun deserialize(decoder: Decoder): Role {
|
||||
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)
|
||||
UnknownRole(originalJson)
|
||||
} else {
|
||||
userRoleFormat.decodeFromJsonElement(
|
||||
serializers.getValue(type),
|
||||
@ -44,14 +44,14 @@ object UserRoleSerializer : KSerializer<UserRole> {
|
||||
}
|
||||
|
||||
@InternalSerializationApi
|
||||
private fun <T : UserRole> T.toJson(): JsonElement {
|
||||
private fun <T : Role> T.toJson(): JsonElement {
|
||||
return userRoleFormat.encodeToJsonElement(this::class.serializer() as KSerializer<T>, this)
|
||||
}
|
||||
|
||||
@InternalSerializationApi
|
||||
override fun serialize(encoder: Encoder, value: UserRole) {
|
||||
override fun serialize(encoder: Encoder, value: Role) {
|
||||
if (encoder is JsonEncoder) {
|
||||
if (value is UnknownUserRole) {
|
||||
if (value is UnknownRole) {
|
||||
encoder.encodeJsonElement(value.originalJson)
|
||||
} else {
|
||||
val valueSerializer = value::class.serializer()
|
||||
@ -70,7 +70,7 @@ object UserRoleSerializer : KSerializer<UserRole> {
|
||||
}
|
||||
}
|
||||
|
||||
fun <T : UserRole> includeSerializer(
|
||||
fun <T : Role> includeSerializer(
|
||||
type: String,
|
||||
kSerializer: KSerializer<T>
|
||||
) { serializers[type] = kSerializer }
|
@ -2,4 +2,4 @@ package dev.inmo.postssystem.features.roles.common
|
||||
|
||||
import kotlinx.serialization.builtins.ListSerializer
|
||||
|
||||
val UserRolesSerializer = ListSerializer(UserRole.serializer())
|
||||
val RolesSerializer = ListSerializer(Role.serializer())
|
||||
|
@ -1,16 +1,42 @@
|
||||
package dev.inmo.postssystem.features.roles.common
|
||||
|
||||
import dev.inmo.postssystem.features.users.common.UserId
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
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
|
||||
@Serializable
|
||||
sealed class RoleSubject
|
||||
@Serializable
|
||||
data class OtherRoleRoleSubject(@Serializable(RoleSerializer::class) val role: Role) : RoleSubject()
|
||||
@Serializable
|
||||
data class UserRoleSubject(val userId: UserId) : RoleSubject()
|
||||
|
||||
interface ReadRolesStorage<T : Role> {
|
||||
suspend fun getSubjects(role: T): List<RoleSubject>
|
||||
suspend fun getRoles(subject: RoleSubject): List<T>
|
||||
suspend fun getRoles(userId: UserId): List<T> = getRoles(UserRoleSubject(userId))
|
||||
suspend fun contains(subject: RoleSubject, role: T): Boolean
|
||||
suspend fun containsAny(subject: RoleSubject, roles: List<T>): Boolean
|
||||
}
|
||||
interface WriteUsersRolesStorage<T : UserRole> {
|
||||
suspend fun include(userId: UserId, userRole: T): Boolean
|
||||
suspend fun exclude(userId: UserId, userRole: T): Boolean
|
||||
suspend fun ReadRolesStorage<Role>.getUsers(
|
||||
userRole: Role
|
||||
): List<UserId> = getSubjects(userRole).flatMap {
|
||||
when (it) {
|
||||
is OtherRoleRoleSubject -> getUsers(it.role)
|
||||
is UserRoleSubject -> listOf(it.userId)
|
||||
}
|
||||
}
|
||||
suspend fun ReadRolesStorage<Role>.contains(
|
||||
userId: UserId,
|
||||
userRole: Role
|
||||
): Boolean = getSubjects(userRole).any {
|
||||
when (it) {
|
||||
is OtherRoleRoleSubject -> contains(userId, it.role)
|
||||
is UserRoleSubject -> userId == it.userId
|
||||
}
|
||||
}
|
||||
interface WriteRolesStorage<T : Role> {
|
||||
suspend fun include(subject: RoleSubject, role: T): Boolean
|
||||
suspend fun exclude(subject: RoleSubject, role: T): Boolean
|
||||
}
|
||||
|
||||
interface UsersRolesStorage<T : UserRole> : ReadUsersRolesStorage<T>, WriteUsersRolesStorage<T>
|
||||
interface RolesStorage<T : Role> : ReadRolesStorage<T>, WriteRolesStorage<T>
|
||||
|
13
features/roles/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/common/keyvalue/KeyValueRolesStorage.kt
Normal file
13
features/roles/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/common/keyvalue/KeyValueRolesStorage.kt
Normal file
@ -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 KeyValueRolesStorage<T : Role>(
|
||||
private val keyValuesRepo: KeyValuesRolesOriginalRepo,
|
||||
private val serializer: KSerializer<T>,
|
||||
private val format: StringFormat = ReadKeyValueRolesStorage.defaultJson
|
||||
) : RolesStorage<T>,
|
||||
ReadRolesStorage<T> by ReadKeyValueRolesStorage(keyValuesRepo, serializer, format),
|
||||
WriteRolesStorage<T> by WriteKeyValueRolesStorage(keyValuesRepo, serializer, format)
|
@ -1,13 +0,0 @@
|
||||
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)
|
@ -2,4 +2,4 @@ package dev.inmo.postssystem.features.roles.common.keyvalue
|
||||
|
||||
import dev.inmo.micro_utils.repos.KeyValuesRepo
|
||||
|
||||
typealias KeyValuesUsersRolesOriginalRepo = KeyValuesRepo<Long, String>
|
||||
typealias KeyValuesRolesOriginalRepo = KeyValuesRepo<String, String>
|
60
features/roles/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/common/keyvalue/ReadKeyValueRolesStorage.kt
Normal file
60
features/roles/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/common/keyvalue/ReadKeyValueRolesStorage.kt
Normal file
@ -0,0 +1,60 @@
|
||||
package dev.inmo.postssystem.features.roles.common.keyvalue
|
||||
|
||||
import dev.inmo.postssystem.features.common.common.default
|
||||
import dev.inmo.postssystem.features.roles.common.*
|
||||
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 ReadKeyValueRolesStorage<T : Role>(
|
||||
private val keyValuesRepo: ReadKeyValuesRepo<String, String>,
|
||||
private val serializer: KSerializer<T>,
|
||||
private val format: StringFormat = defaultJson
|
||||
) : ReadRolesStorage<T> {
|
||||
override suspend fun getSubjects(role: T): List<RoleSubject> {
|
||||
val serialized = format.encodeToString(serializer, role)
|
||||
|
||||
return keyValuesRepo.getAllByWithNextPaging {
|
||||
keys(serialized, it).let { paginationResult ->
|
||||
paginationResult.changeResults(
|
||||
paginationResult.results.map { serializedSubject -> format.decodeFromString(RoleSubject.serializer(), serializedSubject) }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getRoles(subject: RoleSubject): List<T> {
|
||||
val subjectString = format.encodeToString(RoleSubject.serializer(), subject)
|
||||
return keyValuesRepo.getAllByWithNextPaging {
|
||||
get(subjectString, it).let { paginationResult ->
|
||||
paginationResult.changeResults(
|
||||
paginationResult.results.map { serialized ->
|
||||
format.decodeFromString(serializer, serialized)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun contains(subject: RoleSubject, role: T): Boolean {
|
||||
val serialized = format.encodeToString(serializer, role)
|
||||
val subjectString = format.encodeToString(RoleSubject.serializer(), subject)
|
||||
|
||||
return keyValuesRepo.contains(subjectString, serialized)
|
||||
}
|
||||
|
||||
override suspend fun containsAny(subject: RoleSubject, roles: List<T>): Boolean {
|
||||
val subjectString = format.encodeToString(RoleSubject.serializer(), subject)
|
||||
return roles.any {
|
||||
val serialized = format.encodeToString(serializer, it)
|
||||
keyValuesRepo.contains(subjectString, serialized)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
internal val defaultJson = Json.default
|
||||
}
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
|
32
features/roles/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/common/keyvalue/WriteKeyValueRolesStorage.kt
Normal file
32
features/roles/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/common/keyvalue/WriteKeyValueRolesStorage.kt
Normal file
@ -0,0 +1,32 @@
|
||||
package dev.inmo.postssystem.features.roles.common.keyvalue
|
||||
|
||||
import dev.inmo.postssystem.features.roles.common.*
|
||||
import dev.inmo.micro_utils.repos.*
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.StringFormat
|
||||
|
||||
open class WriteKeyValueRolesStorage<T : Role>(
|
||||
private val keyValuesRepo: WriteKeyValuesRepo<String, String>,
|
||||
private val serializer: KSerializer<T>,
|
||||
private val format: StringFormat = ReadKeyValueRolesStorage.defaultJson
|
||||
) : WriteRolesStorage<T> {
|
||||
override suspend fun include(subject: RoleSubject, role: T): Boolean {
|
||||
return runCatching {
|
||||
keyValuesRepo.add(
|
||||
format.encodeToString(RoleSubject.serializer(), subject),
|
||||
format.encodeToString(serializer, role)
|
||||
)
|
||||
true
|
||||
}.getOrElse { false }
|
||||
}
|
||||
|
||||
override suspend fun exclude(subject: RoleSubject, role: T): Boolean {
|
||||
return runCatching {
|
||||
keyValuesRepo.remove(
|
||||
format.encodeToString(RoleSubject.serializer(), subject),
|
||||
format.encodeToString(serializer, role)
|
||||
)
|
||||
true
|
||||
}.getOrElse { false }
|
||||
}
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
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 }
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user