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
@ -4,14 +4,14 @@ import dev.inmo.postssystem.features.roles.common.*
|
||||
import dev.inmo.micro_utils.ktor.client.UnifiedRequester
|
||||
import kotlinx.serialization.KSerializer
|
||||
|
||||
class ClientUsersRolesStorage<T : UserRole>(
|
||||
class ClientRolesStorage<T : Role>(
|
||||
private val baseUrl: String,
|
||||
private val unifiedRequester: UnifiedRequester,
|
||||
private val serializer: KSerializer<T>
|
||||
) : UsersRolesStorage<T>,
|
||||
ReadUsersRolesStorage<T> by ReadClientUsersRolesStorage(
|
||||
) : RolesStorage<T>,
|
||||
ReadRolesStorage<T> by ReadClientRolesStorage(
|
||||
baseUrl, unifiedRequester, serializer
|
||||
),
|
||||
WriteUsersRolesStorage<T> by WriteClientUsersRolesStorage(
|
||||
WriteRolesStorage<T> by WriteClientRolesStorage(
|
||||
baseUrl, unifiedRequester, serializer
|
||||
)
|
||||
|
@ -1,18 +1,17 @@
|
||||
package dev.inmo.postssystem.features.roles.client
|
||||
|
||||
import dev.inmo.postssystem.features.roles.common.*
|
||||
import dev.inmo.postssystem.features.users.common.UserId
|
||||
import dev.inmo.micro_utils.ktor.client.UnifiedRequester
|
||||
import dev.inmo.micro_utils.ktor.common.buildStandardUrl
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.builtins.ListSerializer
|
||||
import kotlinx.serialization.builtins.serializer
|
||||
|
||||
class ReadClientUsersRolesStorage<T : UserRole>(
|
||||
class ReadClientRolesStorage<T : Role>(
|
||||
private val baseUrl: String,
|
||||
private val unifiedRequester: UnifiedRequester,
|
||||
private val serializer: KSerializer<T>
|
||||
) : ReadUsersRolesStorage<T> {
|
||||
) : ReadRolesStorage<T> {
|
||||
private val userRolesSerializer = ListSerializer(serializer)
|
||||
|
||||
private val userRolesFullUrl = buildStandardUrl(
|
||||
@ -20,50 +19,50 @@ class ReadClientUsersRolesStorage<T : UserRole>(
|
||||
usersRolesRootPathPart
|
||||
)
|
||||
|
||||
override suspend fun getUsers(
|
||||
userRole: T
|
||||
): List<UserId> = unifiedRequester.uniget(
|
||||
override suspend fun getSubjects(
|
||||
role: T
|
||||
): List<RoleSubject> = unifiedRequester.uniget(
|
||||
buildStandardUrl(
|
||||
userRolesFullUrl,
|
||||
usersRolesGetUsersPathPart,
|
||||
usersRolesUserRoleQueryParameterName to unifiedRequester.encodeUrlQueryValue(serializer, userRole)
|
||||
usersRolesGetSubjectsPathPart,
|
||||
usersRolesRoleQueryParameterName to unifiedRequester.encodeUrlQueryValue(serializer, role)
|
||||
),
|
||||
UsersIdsSerializer
|
||||
RoleSubjectsSerializer
|
||||
)
|
||||
|
||||
override suspend fun getRoles(
|
||||
userId: UserId
|
||||
subject: RoleSubject
|
||||
): List<T> = unifiedRequester.uniget(
|
||||
buildStandardUrl(
|
||||
userRolesFullUrl,
|
||||
usersRolesGetRolesPathPart,
|
||||
usersRolesUserIdQueryParameterName to unifiedRequester.encodeUrlQueryValue(UserId.serializer(), userId)
|
||||
usersRolesRoleSubjectQueryParameterName to unifiedRequester.encodeUrlQueryValue(RoleSubject.serializer(), subject)
|
||||
),
|
||||
userRolesSerializer
|
||||
)
|
||||
|
||||
override suspend fun contains(
|
||||
userId: UserId,
|
||||
userRole: T
|
||||
subject: RoleSubject,
|
||||
role: T
|
||||
): Boolean = unifiedRequester.uniget(
|
||||
buildStandardUrl(
|
||||
userRolesFullUrl,
|
||||
usersRolesContainsPathPart,
|
||||
usersRolesUserIdQueryParameterName to unifiedRequester.encodeUrlQueryValue(UserId.serializer(), userId),
|
||||
usersRolesUserRoleQueryParameterName to unifiedRequester.encodeUrlQueryValue(serializer, userRole)
|
||||
usersRolesRoleSubjectQueryParameterName to unifiedRequester.encodeUrlQueryValue(RoleSubject.serializer(), subject),
|
||||
usersRolesRoleQueryParameterName to unifiedRequester.encodeUrlQueryValue(serializer, role)
|
||||
),
|
||||
Boolean.serializer()
|
||||
)
|
||||
|
||||
override suspend fun containsAny(
|
||||
userId: UserId,
|
||||
userRoles: List<T>
|
||||
subject: RoleSubject,
|
||||
roles: List<T>
|
||||
): Boolean = unifiedRequester.uniget(
|
||||
buildStandardUrl(
|
||||
userRolesFullUrl,
|
||||
usersRolesContainsAnyPathPart,
|
||||
usersRolesUserIdQueryParameterName to unifiedRequester.encodeUrlQueryValue(UserId.serializer(), userId),
|
||||
usersRolesUserRoleQueryParameterName to unifiedRequester.encodeUrlQueryValue(userRolesSerializer, userRoles)
|
||||
usersRolesRoleSubjectQueryParameterName to unifiedRequester.encodeUrlQueryValue(RoleSubject.serializer(), subject),
|
||||
usersRolesRoleQueryParameterName to unifiedRequester.encodeUrlQueryValue(userRolesSerializer, roles)
|
||||
),
|
||||
Boolean.serializer()
|
||||
)
|
||||
|
@ -1,18 +1,17 @@
|
||||
package dev.inmo.postssystem.features.roles.client
|
||||
|
||||
import dev.inmo.postssystem.features.roles.common.*
|
||||
import dev.inmo.postssystem.features.users.common.UserId
|
||||
import dev.inmo.micro_utils.ktor.client.UnifiedRequester
|
||||
import dev.inmo.micro_utils.ktor.common.buildStandardUrl
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.builtins.serializer
|
||||
|
||||
class WriteClientUsersRolesStorage<T : UserRole>(
|
||||
class WriteClientRolesStorage<T : Role>(
|
||||
private val baseUrl: String,
|
||||
private val unifiedRequester: UnifiedRequester,
|
||||
private val serializer: KSerializer<T>
|
||||
) : WriteUsersRolesStorage<T> {
|
||||
private val wrapperSerializer = UserRolesStorageIncludeExcludeWrapper.serializer(
|
||||
) : WriteRolesStorage<T> {
|
||||
private val wrapperSerializer = RolesStorageIncludeExcludeWrapper.serializer(
|
||||
serializer
|
||||
)
|
||||
private val userRolesFullUrl = buildStandardUrl(
|
||||
@ -29,23 +28,23 @@ class WriteClientUsersRolesStorage<T : UserRole>(
|
||||
)
|
||||
|
||||
override suspend fun include(
|
||||
userId: UserId,
|
||||
userRole: T
|
||||
subject: RoleSubject,
|
||||
role: T
|
||||
): Boolean = unifiedRequester.unipost(
|
||||
includeFullUrl,
|
||||
wrapperSerializer to UserRolesStorageIncludeExcludeWrapper(
|
||||
userId, userRole
|
||||
wrapperSerializer to RolesStorageIncludeExcludeWrapper(
|
||||
subject, role
|
||||
),
|
||||
Boolean.serializer()
|
||||
)
|
||||
|
||||
override suspend fun exclude(
|
||||
userId: UserId,
|
||||
userRole: T
|
||||
subject: RoleSubject,
|
||||
role: T
|
||||
): Boolean = unifiedRequester.unipost(
|
||||
excludeFullUrl,
|
||||
wrapperSerializer to UserRolesStorageIncludeExcludeWrapper(
|
||||
userId, userRole
|
||||
wrapperSerializer to RolesStorageIncludeExcludeWrapper(
|
||||
subject, role
|
||||
),
|
||||
Boolean.serializer()
|
||||
)
|
||||
|
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 }
|
||||
}
|
||||
}
|
@ -1,12 +1,12 @@
|
||||
package dev.inmo.postssystem.features.roles.manager.common
|
||||
|
||||
import dev.inmo.postssystem.features.roles.common.UserRole
|
||||
import dev.inmo.postssystem.features.roles.common.UserRoleSerializer
|
||||
import dev.inmo.postssystem.features.roles.common.Role
|
||||
import dev.inmo.postssystem.features.roles.common.RoleSerializer
|
||||
import dev.inmo.micro_utils.serialization.typed_serializer.TypedSerializer
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable(RolesManagerRoleSerializer::class)
|
||||
interface RolesManagerRole : UserRole {
|
||||
interface RolesManagerRole : Role {
|
||||
companion object {
|
||||
fun serializer() = RolesManagerRoleSerializer
|
||||
}
|
||||
@ -26,7 +26,7 @@ object RolesManagerRoleSerializer : TypedSerializer<RolesManagerRole>(
|
||||
)
|
||||
) {
|
||||
init {
|
||||
UserRoleSerializer.includeSerializer(KEY, RolesManagerRoleSerializer)
|
||||
serializers.forEach { (k, v) -> UserRoleSerializer.includeSerializer(k, v) }
|
||||
RoleSerializer.includeSerializer(KEY, RolesManagerRoleSerializer)
|
||||
serializers.forEach { (k, v) -> RoleSerializer.includeSerializer(k, v) }
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,15 @@
|
||||
package dev.inmo.postssystem.features.roles.manager.common
|
||||
|
||||
import dev.inmo.postssystem.features.common.common.default
|
||||
import dev.inmo.postssystem.features.roles.common.UsersRolesStorage
|
||||
import dev.inmo.postssystem.features.roles.common.RolesStorage
|
||||
import dev.inmo.postssystem.features.roles.common.keyvalue.*
|
||||
import kotlinx.serialization.StringFormat
|
||||
import kotlinx.serialization.json.Json
|
||||
|
||||
class RolesManagerRoleStorage(
|
||||
keyValuesRepo: KeyValuesUsersRolesOriginalRepo,
|
||||
keyValuesRepo: KeyValuesRolesOriginalRepo,
|
||||
format: StringFormat = Json.default
|
||||
) : UsersRolesStorage<RolesManagerRole>, KeyValueUsersRolesStorage<RolesManagerRole>(
|
||||
) : RolesStorage<RolesManagerRole>, KeyValueRolesStorage<RolesManagerRole>(
|
||||
keyValuesRepo,
|
||||
RolesManagerRole.serializer(),
|
||||
format
|
||||
|
@ -1,18 +1,17 @@
|
||||
package dev.inmo.postssystem.features.roles.manager.server
|
||||
|
||||
import dev.inmo.postssystem.features.roles.common.ReadUsersRolesStorage
|
||||
import dev.inmo.postssystem.features.roles.common.UserRole
|
||||
import dev.inmo.postssystem.features.roles.common.*
|
||||
import dev.inmo.postssystem.features.roles.manager.common.GeneralRolesManagerRole
|
||||
import dev.inmo.postssystem.features.roles.server.RolesChecker
|
||||
import dev.inmo.postssystem.features.users.common.User
|
||||
import io.ktor.application.ApplicationCall
|
||||
|
||||
object RolesManagerRolesChecker : RolesChecker<UserRole> {
|
||||
object RolesManagerRolesChecker : RolesChecker<Role> {
|
||||
override val key: String
|
||||
get() = "RolesManagerRolesChecker"
|
||||
|
||||
override suspend fun ApplicationCall.invoke(
|
||||
usersRolesStorage: ReadUsersRolesStorage<UserRole>,
|
||||
usersRolesStorage: ReadRolesStorage<Role>,
|
||||
user: User
|
||||
): Boolean = usersRolesStorage.contains(user.id, GeneralRolesManagerRole)
|
||||
}
|
||||
|
@ -1,16 +1,16 @@
|
||||
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.common.RolesStorage
|
||||
import dev.inmo.postssystem.features.roles.manager.common.RolesManagerRole
|
||||
import dev.inmo.postssystem.features.roles.manager.common.RolesManagerRoleSerializer
|
||||
import dev.inmo.postssystem.features.roles.server.UsersRolesStorageWriteServerRoutesConfigurator
|
||||
import dev.inmo.postssystem.features.roles.server.RolesStorageWriteServerRoutesConfigurator
|
||||
import dev.inmo.micro_utils.ktor.server.configurators.ApplicationRoutingConfigurator
|
||||
|
||||
class RolesManagerUsersRolesStorageServerRoutesConfigurator(
|
||||
storage: UsersRolesStorage<RolesManagerRole>,
|
||||
class RolesManagerRolesStorageServerRoutesConfigurator(
|
||||
storage: RolesStorage<RolesManagerRole>,
|
||||
unifiedRouter: UnifiedRouter
|
||||
) : ApplicationRoutingConfigurator.Element by UsersRolesStorageWriteServerRoutesConfigurator(
|
||||
) : ApplicationRoutingConfigurator.Element by RolesStorageWriteServerRoutesConfigurator(
|
||||
storage,
|
||||
RolesManagerRoleSerializer,
|
||||
RolesManagerRolesChecker.key,
|
||||
|
12
features/roles/server/src/jvmMain/kotlin/dev/inmo/postssystem/features/roles/server/RolesChecker.kt
12
features/roles/server/src/jvmMain/kotlin/dev/inmo/postssystem/features/roles/server/RolesChecker.kt
@ -4,24 +4,24 @@ import dev.inmo.postssystem.features.roles.common.*
|
||||
import dev.inmo.postssystem.features.users.common.User
|
||||
import io.ktor.application.ApplicationCall
|
||||
|
||||
interface RolesChecker<T : UserRole> {
|
||||
interface RolesChecker<T : Role> {
|
||||
val key: String
|
||||
|
||||
suspend operator fun ApplicationCall.invoke(
|
||||
usersRolesStorage: ReadUsersRolesStorage<T>,
|
||||
usersRolesStorage: ReadRolesStorage<T>,
|
||||
user: User
|
||||
): Boolean
|
||||
|
||||
companion object {
|
||||
fun <T : UserRole> default(
|
||||
fun default(
|
||||
key: String,
|
||||
role: T
|
||||
): RolesChecker<T> = object : RolesChecker<T> {
|
||||
role: Role
|
||||
): RolesChecker<Role> = object : RolesChecker<Role> {
|
||||
override val key: String
|
||||
get() = key
|
||||
|
||||
override suspend fun ApplicationCall.invoke(
|
||||
usersRolesStorage: ReadUsersRolesStorage<T>,
|
||||
usersRolesStorage: ReadRolesStorage<Role>,
|
||||
user: User
|
||||
): Boolean = usersRolesStorage.contains(user.id, role)
|
||||
}
|
||||
|
@ -9,19 +9,19 @@ import io.ktor.routing.*
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.builtins.serializer
|
||||
|
||||
class UsersRolesStorageWriteServerRoutesConfigurator<T : UserRole>(
|
||||
private val storage: WriteUsersRolesStorage<T>,
|
||||
class RolesStorageWriteServerRoutesConfigurator<T : Role>(
|
||||
private val storage: WriteRolesStorage<T>,
|
||||
private val serializer: KSerializer<T>,
|
||||
private val includeAuthKey: String,
|
||||
private val excludeAuthKey: String = includeAuthKey,
|
||||
private val unifiedRouter: UnifiedRouter
|
||||
) : ApplicationRoutingConfigurator.Element {
|
||||
override fun Route.invoke() {
|
||||
unifiedRouter.apply {
|
||||
route(usersRolesRootPathPart) {
|
||||
val wrapperSerializer = UserRolesStorageIncludeExcludeWrapper.serializer(
|
||||
serializer
|
||||
)
|
||||
route(usersRolesRootPathPart) {
|
||||
val wrapperSerializer = RolesStorageIncludeExcludeWrapper.serializer(
|
||||
serializer
|
||||
)
|
||||
unifiedRouter.apply {
|
||||
authenticate(includeAuthKey) {
|
||||
post(usersRolesIncludePathPart) {
|
||||
val wrapper = uniload(wrapperSerializer)
|
||||
@ -29,7 +29,7 @@ class UsersRolesStorageWriteServerRoutesConfigurator<T : UserRole>(
|
||||
unianswer(
|
||||
Boolean.serializer(),
|
||||
storage.include(
|
||||
wrapper.userId,
|
||||
wrapper.subject,
|
||||
wrapper.userRole
|
||||
)
|
||||
)
|
||||
@ -42,7 +42,7 @@ class UsersRolesStorageWriteServerRoutesConfigurator<T : UserRole>(
|
||||
unianswer(
|
||||
Boolean.serializer(),
|
||||
storage.exclude(
|
||||
wrapper.userId,
|
||||
wrapper.subject,
|
||||
wrapper.userRole
|
||||
)
|
||||
)
|
@ -1,39 +1,37 @@
|
||||
package dev.inmo.postssystem.features.roles.server
|
||||
|
||||
import dev.inmo.postssystem.features.roles.common.UserRole
|
||||
import dev.inmo.postssystem.features.roles.common.UsersRolesStorage
|
||||
import dev.inmo.postssystem.features.users.common.UserId
|
||||
import dev.inmo.postssystem.features.roles.common.*
|
||||
|
||||
class UsersRolesAggregator(
|
||||
private val otherStorages: List<UsersRolesStorageHolder<*>>
|
||||
) : UsersRolesStorage<UserRole> {
|
||||
class RolesAggregator(
|
||||
private val otherStorages: List<RolesStorageHolder<*>>
|
||||
) : RolesStorage<Role> {
|
||||
private val otherStoragesByClass = otherStorages.associateBy { it.kclass }
|
||||
|
||||
override suspend fun getUsers(userRole: UserRole): List<UserId> {
|
||||
return otherStoragesByClass[userRole::class] ?.getUsers(userRole) ?: emptyList()
|
||||
override suspend fun getSubjects(role: Role): List<RoleSubject> {
|
||||
return otherStoragesByClass[role::class] ?.getUsers(role) ?: emptyList()
|
||||
}
|
||||
|
||||
override suspend fun getRoles(userId: UserId): List<UserRole> = otherStorages.flatMap { it.getRoles(userId) }
|
||||
override suspend fun getRoles(subject: RoleSubject): List<Role> = otherStorages.flatMap { it.getRoles(subject) }
|
||||
|
||||
override suspend fun contains(userId: UserId, userRole: UserRole): Boolean {
|
||||
return otherStoragesByClass[userRole::class] ?.contains(userId, userRole) ?: false
|
||||
override suspend fun contains(subject: RoleSubject, role: Role): Boolean {
|
||||
return otherStoragesByClass[role::class] ?.contains(subject, role) ?: false
|
||||
}
|
||||
|
||||
override suspend fun containsAny(userId: UserId, userRoles: List<UserRole>): Boolean {
|
||||
return userRoles.any {
|
||||
contains(userId, it)
|
||||
override suspend fun containsAny(subject: RoleSubject, roles: List<Role>): Boolean {
|
||||
return roles.any {
|
||||
contains(subject, it)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun include(
|
||||
userId: UserId,
|
||||
userRole: UserRole
|
||||
): Boolean = otherStoragesByClass[userRole::class] ?.include(userId, userRole) ?: false
|
||||
subject: RoleSubject,
|
||||
role: Role
|
||||
): Boolean = otherStoragesByClass[role::class] ?.include(subject, role) ?: false
|
||||
|
||||
override suspend fun exclude(
|
||||
userId: UserId,
|
||||
userRole: UserRole
|
||||
subject: RoleSubject,
|
||||
role: Role
|
||||
): Boolean {
|
||||
return otherStoragesByClass[userRole::class] ?.exclude(userId, userRole) ?: false
|
||||
return otherStoragesByClass[role::class] ?.exclude(subject, role) ?: false
|
||||
}
|
||||
}
|
||||
|
@ -4,18 +4,18 @@ import dev.inmo.postssystem.features.auth.common.AuthToken
|
||||
import dev.inmo.postssystem.features.auth.server.principal
|
||||
import dev.inmo.postssystem.features.auth.server.tokens.AuthTokensService
|
||||
import dev.inmo.postssystem.features.common.server.sessions.ApplicationAuthenticationConfigurator
|
||||
import dev.inmo.postssystem.features.roles.common.UserRole
|
||||
import dev.inmo.postssystem.features.roles.common.UsersRolesStorage
|
||||
import dev.inmo.postssystem.features.roles.common.Role
|
||||
import dev.inmo.postssystem.features.roles.common.RolesStorage
|
||||
import io.ktor.application.call
|
||||
import io.ktor.auth.Authentication
|
||||
import io.ktor.auth.session
|
||||
import io.ktor.http.HttpStatusCode
|
||||
import io.ktor.response.respond
|
||||
|
||||
class UsersRolesAuthenticationConfigurator<T : UserRole>(
|
||||
private val usersRolesStorage: UsersRolesStorage<T>,
|
||||
class RolesAuthenticationConfigurator<T : Role>(
|
||||
private val usersRolesStorage: RolesStorage<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 ->
|
||||
|
@ -1,42 +1,40 @@
|
||||
package dev.inmo.postssystem.features.roles.server
|
||||
|
||||
import dev.inmo.postssystem.features.roles.common.UserRole
|
||||
import dev.inmo.postssystem.features.roles.common.UsersRolesStorage
|
||||
import dev.inmo.postssystem.features.users.common.UserId
|
||||
import dev.inmo.postssystem.features.roles.common.*
|
||||
import dev.inmo.micro_utils.common.*
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
data class UsersRolesStorageHolder<T : UserRole>(
|
||||
data class RolesStorageHolder<T : Role>(
|
||||
val kclass: KClass<T>,
|
||||
val storage: UsersRolesStorage<T>
|
||||
val storage: RolesStorage<T>
|
||||
) {
|
||||
private suspend fun <R> doIfRelevant(
|
||||
userRole: UserRole,
|
||||
role: Role,
|
||||
block: suspend (T) -> R
|
||||
): Optional<R> = if (kclass.isInstance(userRole)) {
|
||||
block(userRole as T).optional
|
||||
): Optional<R> = if (kclass.isInstance(role)) {
|
||||
block(role as T).optional
|
||||
} else {
|
||||
Optional.absent()
|
||||
}
|
||||
|
||||
suspend fun getUsers(userRole: UserRole): List<UserId>? = doIfRelevant(userRole) {
|
||||
storage.getUsers(it)
|
||||
suspend fun getUsers(role: Role): List<RoleSubject>? = doIfRelevant(role) {
|
||||
storage.getSubjects(it)
|
||||
}.dataOrNull()
|
||||
|
||||
suspend fun getRoles(userId: UserId): List<UserRole> = storage.getRoles(userId)
|
||||
suspend fun getRoles(subject: RoleSubject): List<Role> = storage.getRoles(subject)
|
||||
|
||||
suspend fun contains(userId: UserId, userRole: UserRole): Boolean? = doIfRelevant(userRole) {
|
||||
storage.contains(userId, it)
|
||||
suspend fun contains(subject: RoleSubject, role: Role): Boolean? = doIfRelevant(role) {
|
||||
storage.contains(subject, it)
|
||||
}.dataOrNull()
|
||||
|
||||
suspend fun include(
|
||||
userId: UserId,
|
||||
userRole: UserRole
|
||||
): Boolean? = doIfRelevant(userRole) {
|
||||
storage.include(userId, it)
|
||||
subject: RoleSubject,
|
||||
role: Role
|
||||
): Boolean? = doIfRelevant(role) {
|
||||
storage.include(subject, it)
|
||||
}.dataOrNull()
|
||||
|
||||
suspend fun exclude(userId: UserId, userRole: UserRole): Boolean? = doIfRelevant(userRole) {
|
||||
storage.exclude(userId, it)
|
||||
suspend fun exclude(subject: RoleSubject, role: Role): Boolean? = doIfRelevant(role) {
|
||||
storage.exclude(subject, it)
|
||||
}.dataOrNull()
|
||||
}
|
||||
|
@ -1,18 +1,16 @@
|
||||
package dev.inmo.postssystem.features.roles.server
|
||||
|
||||
import dev.inmo.postssystem.features.roles.common.*
|
||||
import dev.inmo.postssystem.features.users.common.UserId
|
||||
import dev.inmo.micro_utils.ktor.server.*
|
||||
import dev.inmo.micro_utils.ktor.server.configurators.ApplicationRoutingConfigurator
|
||||
import io.ktor.application.call
|
||||
import io.ktor.auth.authenticate
|
||||
import io.ktor.routing.*
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.builtins.ListSerializer
|
||||
import kotlinx.serialization.builtins.serializer
|
||||
|
||||
class UsersRolesStorageReadServerRoutesConfigurator<T : UserRole>(
|
||||
private val storage: ReadUsersRolesStorage<T>,
|
||||
class RolesStorageReadServerRoutesConfigurator<T : Role>(
|
||||
private val storage: ReadRolesStorage<T>,
|
||||
private val serializer: KSerializer<T>,
|
||||
private val unifiedRouter: UnifiedRouter
|
||||
) : ApplicationRoutingConfigurator.Element {
|
||||
@ -21,51 +19,53 @@ class UsersRolesStorageReadServerRoutesConfigurator<T : UserRole>(
|
||||
unifiedRouter.apply {
|
||||
authenticate {
|
||||
route(usersRolesRootPathPart) {
|
||||
get(usersRolesGetUsersPathPart) {
|
||||
val userRole = decodeUrlQueryValueOrSendError(usersRolesUserRoleQueryParameterName, serializer)
|
||||
get(usersRolesGetSubjectsPathPart) {
|
||||
val role = decodeUrlQueryValueOrSendError(usersRolesRoleQueryParameterName, serializer)
|
||||
?: return@get
|
||||
unianswer(
|
||||
UsersIdsSerializer,
|
||||
storage.getUsers(userRole)
|
||||
RoleSubjectsSerializer,
|
||||
storage.getSubjects(role)
|
||||
)
|
||||
}
|
||||
|
||||
get(usersRolesGetRolesPathPart) {
|
||||
val userId = decodeUrlQueryValueOrSendError(usersRolesUserIdQueryParameterName, UserId.serializer())
|
||||
?: return@get
|
||||
val subject = decodeUrlQueryValueOrSendError(
|
||||
usersRolesRoleSubjectQueryParameterName,
|
||||
RoleSubject.serializer()
|
||||
) ?: return@get
|
||||
unianswer(
|
||||
userRolesSerializer,
|
||||
storage.getRoles(userId)
|
||||
storage.getRoles(subject)
|
||||
)
|
||||
}
|
||||
|
||||
get(usersRolesContainsPathPart) {
|
||||
val userId = decodeUrlQueryValueOrSendError(
|
||||
usersRolesUserIdQueryParameterName,
|
||||
UserId.serializer()
|
||||
val subject = decodeUrlQueryValueOrSendError(
|
||||
usersRolesRoleSubjectQueryParameterName,
|
||||
RoleSubject.serializer()
|
||||
) ?: return@get
|
||||
val userRole = decodeUrlQueryValueOrSendError(
|
||||
usersRolesUserRoleQueryParameterName,
|
||||
val role = decodeUrlQueryValueOrSendError(
|
||||
usersRolesRoleQueryParameterName,
|
||||
serializer
|
||||
) ?: return@get
|
||||
unianswer(
|
||||
Boolean.serializer(),
|
||||
storage.contains(userId, userRole)
|
||||
storage.contains(subject, role)
|
||||
)
|
||||
}
|
||||
|
||||
get(usersRolesContainsAnyPathPart) {
|
||||
val userId = decodeUrlQueryValueOrSendError(
|
||||
usersRolesUserIdQueryParameterName,
|
||||
UserId.serializer()
|
||||
val subject = decodeUrlQueryValueOrSendError(
|
||||
usersRolesRoleSubjectQueryParameterName,
|
||||
RoleSubject.serializer()
|
||||
) ?: return@get
|
||||
val userRoles = decodeUrlQueryValueOrSendError(
|
||||
usersRolesUserRoleQueryParameterName,
|
||||
usersRolesRoleQueryParameterName,
|
||||
userRolesSerializer
|
||||
) ?: return@get
|
||||
unianswer(
|
||||
Boolean.serializer(),
|
||||
storage.containsAny(userId, userRoles)
|
||||
storage.containsAny(subject, userRoles)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user