diff --git a/client/src/commonMain/kotlin/dev/inmo/postssystem/client/DI.kt b/client/src/commonMain/kotlin/dev/inmo/postssystem/client/DI.kt index 11511170..92bbff6e 100644 --- a/client/src/commonMain/kotlin/dev/inmo/postssystem/client/DI.kt +++ b/client/src/commonMain/kotlin/dev/inmo/postssystem/client/DI.kt @@ -5,9 +5,9 @@ import dev.inmo.postssystem.features.auth.client.installClientAuthenticator import dev.inmo.postssystem.features.auth.common.* import dev.inmo.postssystem.features.files.client.ClientFilesStorage import dev.inmo.postssystem.features.files.common.storage.FilesStorage -import dev.inmo.postssystem.features.roles.common.UserRole -import dev.inmo.postssystem.features.roles.common.UsersRolesStorage -import dev.inmo.postssystem.features.roles.client.ClientUsersRolesStorage +import dev.inmo.postssystem.features.roles.common.Role +import dev.inmo.postssystem.features.roles.common.RolesStorage +import dev.inmo.postssystem.features.roles.client.ClientRolesStorage import dev.inmo.postssystem.features.roles.manager.common.RolesManagerRoleSerializer import dev.inmo.postssystem.features.users.client.UsersStorageKtorClient import dev.inmo.postssystem.features.users.common.ReadUsersStorage @@ -47,7 +47,7 @@ import org.koin.dsl.module val UIScopeQualifier = StringQualifier("CoroutineScopeUI") val SettingsQualifier = StringQualifier("Settings") -val UserRolesQualifier = StringQualifier("UserRoles") +val RolesQualifier = StringQualifier("Roles") private val FSMHandlersBuilderQualifier = StringQualifier("FSMHandlersBuilder") val defaultSerialFormat = Json { @@ -131,6 +131,6 @@ fun getAuthorizedFeaturesDIModule( single { ClientFilesStorage(get(serverUrlQualifier), get(), get()) } single { UsersStorageKtorClient(get(serverUrlQualifier), get()) } - single> { ClientUsersRolesStorage(get(serverUrlQualifier), get(), UserRole.serializer()) } + single> { ClientRolesStorage(get(serverUrlQualifier), get(), Role.serializer()) } } } diff --git a/client/src/commonMain/kotlin/dev/inmo/postssystem/client/settings/auth/AuthSettings.kt b/client/src/commonMain/kotlin/dev/inmo/postssystem/client/settings/auth/AuthSettings.kt index 01b73d85..56a56215 100644 --- a/client/src/commonMain/kotlin/dev/inmo/postssystem/client/settings/auth/AuthSettings.kt +++ b/client/src/commonMain/kotlin/dev/inmo/postssystem/client/settings/auth/AuthSettings.kt @@ -2,7 +2,7 @@ package dev.inmo.postssystem.client.settings.auth import dev.inmo.postssystem.features.auth.client.ui.AuthUIError import dev.inmo.postssystem.features.auth.common.AuthCreds -import dev.inmo.postssystem.features.roles.common.UserRole +import dev.inmo.postssystem.features.roles.common.Role import dev.inmo.postssystem.features.users.common.User import kotlinx.coroutines.Job import kotlinx.coroutines.flow.StateFlow @@ -11,7 +11,7 @@ import org.koin.core.module.Module interface AuthSettings { val authorizedDIModule: StateFlow val user: StateFlow - val userRoles: StateFlow> + val userRoles: StateFlow> val loadingJob: Job suspend fun auth(serverUrl: String, creds: AuthCreds): AuthUIError? diff --git a/client/src/commonMain/kotlin/dev/inmo/postssystem/client/settings/auth/DefaultAuthSettings.kt b/client/src/commonMain/kotlin/dev/inmo/postssystem/client/settings/auth/DefaultAuthSettings.kt index 04c9b8d9..2570b54d 100644 --- a/client/src/commonMain/kotlin/dev/inmo/postssystem/client/settings/auth/DefaultAuthSettings.kt +++ b/client/src/commonMain/kotlin/dev/inmo/postssystem/client/settings/auth/DefaultAuthSettings.kt @@ -5,8 +5,8 @@ import dev.inmo.postssystem.client.getAuthorizedFeaturesDIModule import dev.inmo.postssystem.features.auth.client.AuthUnavailableException import dev.inmo.postssystem.features.auth.client.ui.* import dev.inmo.postssystem.features.auth.common.* -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 dev.inmo.postssystem.features.status.client.StatusFeatureClient import dev.inmo.postssystem.features.users.common.User import dev.inmo.micro_utils.common.Either @@ -29,8 +29,8 @@ data class DefaultAuthSettings( override val authorizedDIModule: StateFlow = _authorizedDIModule.asStateFlow() private val _user = MutableStateFlow(null) override val user: StateFlow = _user.asStateFlow() - private val _userRoles = MutableStateFlow>(emptyList()) - override val userRoles: StateFlow> = _userRoles.asStateFlow() + private val _userRoles = MutableStateFlow>(emptyList()) + override val userRoles: StateFlow> = _userRoles.asStateFlow() private suspend fun getCurrentServerURL() = repo.get(SERVER_URL_FIELD) as? String private suspend fun getCurrentUsername() = repo.get(USERNAME_FIELD) as? String @@ -48,7 +48,7 @@ data class DefaultAuthSettings( if (user == null || authorizedDIModule.value == null) { _userRoles.value = emptyList() } else { - _userRoles.value = koin.get>().getRoles(user.id) + _userRoles.value = koin.get>().getRoles(user.id) } println(user) println(userRoles.value) diff --git a/features/roles/client/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/client/ClientUsersRolesStorage.kt b/features/roles/client/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/client/ClientUsersRolesStorage.kt index e1531e4f..9110e5d1 100644 --- a/features/roles/client/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/client/ClientUsersRolesStorage.kt +++ b/features/roles/client/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/client/ClientUsersRolesStorage.kt @@ -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( +class ClientRolesStorage( private val baseUrl: String, private val unifiedRequester: UnifiedRequester, private val serializer: KSerializer -) : UsersRolesStorage, - ReadUsersRolesStorage by ReadClientUsersRolesStorage( +) : RolesStorage, + ReadRolesStorage by ReadClientRolesStorage( baseUrl, unifiedRequester, serializer ), - WriteUsersRolesStorage by WriteClientUsersRolesStorage( + WriteRolesStorage by WriteClientRolesStorage( baseUrl, unifiedRequester, serializer ) diff --git a/features/roles/client/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/client/ReadClientUsersRolesStorage.kt b/features/roles/client/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/client/ReadClientUsersRolesStorage.kt index 696f833e..48f0cfb2 100644 --- a/features/roles/client/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/client/ReadClientUsersRolesStorage.kt +++ b/features/roles/client/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/client/ReadClientUsersRolesStorage.kt @@ -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( +class ReadClientRolesStorage( private val baseUrl: String, private val unifiedRequester: UnifiedRequester, private val serializer: KSerializer -) : ReadUsersRolesStorage { +) : ReadRolesStorage { private val userRolesSerializer = ListSerializer(serializer) private val userRolesFullUrl = buildStandardUrl( @@ -20,50 +19,50 @@ class ReadClientUsersRolesStorage( usersRolesRootPathPart ) - override suspend fun getUsers( - userRole: T - ): List = unifiedRequester.uniget( + override suspend fun getSubjects( + role: T + ): List = 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 = 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 + subject: RoleSubject, + roles: List ): 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() ) diff --git a/features/roles/client/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/client/WriteClientUsersRolesStorage.kt b/features/roles/client/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/client/WriteClientUsersRolesStorage.kt index 781988cc..f3065a4e 100644 --- a/features/roles/client/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/client/WriteClientUsersRolesStorage.kt +++ b/features/roles/client/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/client/WriteClientUsersRolesStorage.kt @@ -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( +class WriteClientRolesStorage( private val baseUrl: String, private val unifiedRequester: UnifiedRequester, private val serializer: KSerializer -) : WriteUsersRolesStorage { - private val wrapperSerializer = UserRolesStorageIncludeExcludeWrapper.serializer( +) : WriteRolesStorage { + private val wrapperSerializer = RolesStorageIncludeExcludeWrapper.serializer( serializer ) private val userRolesFullUrl = buildStandardUrl( @@ -29,23 +28,23 @@ class WriteClientUsersRolesStorage( ) 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() ) diff --git a/features/roles/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/common/Constants.kt b/features/roles/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/common/Constants.kt index 5bbece7c..ce4bca4c 100644 --- a/features/roles/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/common/Constants.kt +++ b/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( - val userId: UserId, +data class RolesStorageIncludeExcludeWrapper( + val subject: RoleSubject, val userRole: T ) diff --git a/features/roles/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/common/UserRole.kt b/features/roles/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/common/Role.kt similarity index 77% rename from features/roles/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/common/UserRole.kt rename to features/roles/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/common/Role.kt index 1526f7e3..b455fa7d 100644 --- a/features/roles/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/common/UserRole.kt +++ b/features/roles/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/common/Role.kt @@ -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 { +@Serializer(Role::class) +object RoleSerializer : KSerializer { private val userRoleFormat = Json { ignoreUnknownKeys = true } private const val keyField = "key" private const val valueField = "value" - private val serializers = mutableMapOf>() + private val serializers = mutableMapOf>() 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 { } @InternalSerializationApi - private fun T.toJson(): JsonElement { + private fun T.toJson(): JsonElement { return userRoleFormat.encodeToJsonElement(this::class.serializer() as KSerializer, 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 { } } - fun includeSerializer( + fun includeSerializer( type: String, kSerializer: KSerializer ) { serializers[type] = kSerializer } diff --git a/features/roles/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/common/UserRolesSerializer.kt b/features/roles/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/common/UserRolesSerializer.kt index 0d758b68..01fa26e2 100644 --- a/features/roles/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/common/UserRolesSerializer.kt +++ b/features/roles/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/common/UserRolesSerializer.kt @@ -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()) diff --git a/features/roles/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/common/UsersRolesStorage.kt b/features/roles/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/common/UsersRolesStorage.kt index 2751872a..d3b5194f 100644 --- a/features/roles/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/common/UsersRolesStorage.kt +++ b/features/roles/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/common/UsersRolesStorage.kt @@ -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 { - suspend fun getUsers(userRole: T): List - suspend fun getRoles(userId: UserId): List - suspend fun contains(userId: UserId, userRole: T): Boolean - suspend fun containsAny(userId: UserId, userRoles: List): 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 { + suspend fun getSubjects(role: T): List + suspend fun getRoles(subject: RoleSubject): List + suspend fun getRoles(userId: UserId): List = getRoles(UserRoleSubject(userId)) + suspend fun contains(subject: RoleSubject, role: T): Boolean + suspend fun containsAny(subject: RoleSubject, roles: List): Boolean } -interface WriteUsersRolesStorage { - suspend fun include(userId: UserId, userRole: T): Boolean - suspend fun exclude(userId: UserId, userRole: T): Boolean +suspend fun ReadRolesStorage.getUsers( + userRole: Role +): List = getSubjects(userRole).flatMap { + when (it) { + is OtherRoleRoleSubject -> getUsers(it.role) + is UserRoleSubject -> listOf(it.userId) + } +} +suspend fun ReadRolesStorage.contains( + userId: UserId, + userRole: Role +): Boolean = getSubjects(userRole).any { + when (it) { + is OtherRoleRoleSubject -> contains(userId, it.role) + is UserRoleSubject -> userId == it.userId + } +} +interface WriteRolesStorage { + suspend fun include(subject: RoleSubject, role: T): Boolean + suspend fun exclude(subject: RoleSubject, role: T): Boolean } -interface UsersRolesStorage : ReadUsersRolesStorage, WriteUsersRolesStorage +interface RolesStorage : ReadRolesStorage, WriteRolesStorage diff --git a/features/roles/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/common/keyvalue/KeyValueRolesStorage.kt b/features/roles/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/common/keyvalue/KeyValueRolesStorage.kt new file mode 100644 index 00000000..d7aa411b --- /dev/null +++ b/features/roles/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/common/keyvalue/KeyValueRolesStorage.kt @@ -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( + private val keyValuesRepo: KeyValuesRolesOriginalRepo, + private val serializer: KSerializer, + private val format: StringFormat = ReadKeyValueRolesStorage.defaultJson +) : RolesStorage, + ReadRolesStorage by ReadKeyValueRolesStorage(keyValuesRepo, serializer, format), + WriteRolesStorage by WriteKeyValueRolesStorage(keyValuesRepo, serializer, format) diff --git a/features/roles/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/common/keyvalue/KeyValueUsersRolesStorage.kt b/features/roles/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/common/keyvalue/KeyValueUsersRolesStorage.kt deleted file mode 100644 index 83bff41e..00000000 --- a/features/roles/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/common/keyvalue/KeyValueUsersRolesStorage.kt +++ /dev/null @@ -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( - private val keyValuesRepo: KeyValuesUsersRolesOriginalRepo, - private val serializer: KSerializer, - private val format: StringFormat = ReadKeyValueUsersRolesStorage.defaultJson -) : UsersRolesStorage, - ReadUsersRolesStorage by ReadKeyValueUsersRolesStorage(keyValuesRepo, serializer, format), - WriteUsersRolesStorage by WriteKeyValueUsersRolesStorage(keyValuesRepo, serializer, format) diff --git a/features/roles/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/common/keyvalue/KeyValueOriginalRepoTypealias.kt b/features/roles/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/common/keyvalue/KeyValuesRolesOriginalRepo.kt similarity index 60% rename from features/roles/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/common/keyvalue/KeyValueOriginalRepoTypealias.kt rename to features/roles/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/common/keyvalue/KeyValuesRolesOriginalRepo.kt index d5aaead8..a5960429 100644 --- a/features/roles/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/common/keyvalue/KeyValueOriginalRepoTypealias.kt +++ b/features/roles/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/common/keyvalue/KeyValuesRolesOriginalRepo.kt @@ -2,4 +2,4 @@ package dev.inmo.postssystem.features.roles.common.keyvalue import dev.inmo.micro_utils.repos.KeyValuesRepo -typealias KeyValuesUsersRolesOriginalRepo = KeyValuesRepo +typealias KeyValuesRolesOriginalRepo = KeyValuesRepo diff --git a/features/roles/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/common/keyvalue/ReadKeyValueRolesStorage.kt b/features/roles/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/common/keyvalue/ReadKeyValueRolesStorage.kt new file mode 100644 index 00000000..ddbab58b --- /dev/null +++ b/features/roles/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/common/keyvalue/ReadKeyValueRolesStorage.kt @@ -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( + private val keyValuesRepo: ReadKeyValuesRepo, + private val serializer: KSerializer, + private val format: StringFormat = defaultJson +) : ReadRolesStorage { + override suspend fun getSubjects(role: T): List { + 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 { + 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): 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 + } +} diff --git a/features/roles/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/common/keyvalue/ReadKeyValueUsersRolesStorage.kt b/features/roles/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/common/keyvalue/ReadKeyValueUsersRolesStorage.kt deleted file mode 100644 index 4d4fd21d..00000000 --- a/features/roles/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/common/keyvalue/ReadKeyValueUsersRolesStorage.kt +++ /dev/null @@ -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( - private val keyValuesRepo: ReadKeyValuesRepo, - private val serializer: KSerializer, - private val format: StringFormat = defaultJson -) : ReadUsersRolesStorage { - override suspend fun getUsers(userRole: T): List { - 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 { - 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): Boolean { - return userRoles.any { - contains(userId, it) - } - } - - companion object { - internal val defaultJson = Json.default - } -} - diff --git a/features/roles/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/common/keyvalue/WriteKeyValueRolesStorage.kt b/features/roles/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/common/keyvalue/WriteKeyValueRolesStorage.kt new file mode 100644 index 00000000..3fe04b25 --- /dev/null +++ b/features/roles/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/common/keyvalue/WriteKeyValueRolesStorage.kt @@ -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( + private val keyValuesRepo: WriteKeyValuesRepo, + private val serializer: KSerializer, + private val format: StringFormat = ReadKeyValueRolesStorage.defaultJson +) : WriteRolesStorage { + 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 } + } +} diff --git a/features/roles/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/common/keyvalue/WriteKeyValueUsersRolesStorage.kt b/features/roles/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/common/keyvalue/WriteKeyValueUsersRolesStorage.kt deleted file mode 100644 index 59c4aeb3..00000000 --- a/features/roles/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/common/keyvalue/WriteKeyValueUsersRolesStorage.kt +++ /dev/null @@ -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( - private val keyValuesRepo: WriteKeyValuesRepo, - private val serializer: KSerializer, - private val format: StringFormat = ReadKeyValueUsersRolesStorage.defaultJson -) : WriteUsersRolesStorage { - 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 } - } -} diff --git a/features/roles/manager/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/manager/common/RolesManagerRole.kt b/features/roles/manager/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/manager/common/RolesManagerRole.kt index 8a9b6669..4ca607e0 100644 --- a/features/roles/manager/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/manager/common/RolesManagerRole.kt +++ b/features/roles/manager/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/manager/common/RolesManagerRole.kt @@ -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( ) ) { 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) } } } diff --git a/features/roles/manager/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/manager/common/RolesManagerRoleStorage.kt b/features/roles/manager/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/manager/common/RolesManagerRoleStorage.kt index b8e26d90..019c630b 100644 --- a/features/roles/manager/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/manager/common/RolesManagerRoleStorage.kt +++ b/features/roles/manager/common/src/commonMain/kotlin/dev/inmo/postssystem/features/roles/manager/common/RolesManagerRoleStorage.kt @@ -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, KeyValueUsersRolesStorage( +) : RolesStorage, KeyValueRolesStorage( keyValuesRepo, RolesManagerRole.serializer(), format diff --git a/features/roles/manager/server/src/jvmMain/kotlin/dev/inmo/postssystem/features/roles/manager/server/RolesManagerRolesChecker.kt b/features/roles/manager/server/src/jvmMain/kotlin/dev/inmo/postssystem/features/roles/manager/server/RolesManagerRolesChecker.kt index daffb0ce..d65211e3 100644 --- a/features/roles/manager/server/src/jvmMain/kotlin/dev/inmo/postssystem/features/roles/manager/server/RolesManagerRolesChecker.kt +++ b/features/roles/manager/server/src/jvmMain/kotlin/dev/inmo/postssystem/features/roles/manager/server/RolesManagerRolesChecker.kt @@ -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 { +object RolesManagerRolesChecker : RolesChecker { override val key: String get() = "RolesManagerRolesChecker" override suspend fun ApplicationCall.invoke( - usersRolesStorage: ReadUsersRolesStorage, + usersRolesStorage: ReadRolesStorage, user: User ): Boolean = usersRolesStorage.contains(user.id, GeneralRolesManagerRole) } diff --git a/features/roles/manager/server/src/jvmMain/kotlin/dev/inmo/postssystem/features/roles/manager/server/RolesManagerUsersRolesStorageServerRoutesConfigurator.kt b/features/roles/manager/server/src/jvmMain/kotlin/dev/inmo/postssystem/features/roles/manager/server/RolesManagerUsersRolesStorageServerRoutesConfigurator.kt index f28dc4c2..99e4ad46 100644 --- a/features/roles/manager/server/src/jvmMain/kotlin/dev/inmo/postssystem/features/roles/manager/server/RolesManagerUsersRolesStorageServerRoutesConfigurator.kt +++ b/features/roles/manager/server/src/jvmMain/kotlin/dev/inmo/postssystem/features/roles/manager/server/RolesManagerUsersRolesStorageServerRoutesConfigurator.kt @@ -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, +class RolesManagerRolesStorageServerRoutesConfigurator( + storage: RolesStorage, unifiedRouter: UnifiedRouter -) : ApplicationRoutingConfigurator.Element by UsersRolesStorageWriteServerRoutesConfigurator( +) : ApplicationRoutingConfigurator.Element by RolesStorageWriteServerRoutesConfigurator( storage, RolesManagerRoleSerializer, RolesManagerRolesChecker.key, diff --git a/features/roles/server/src/jvmMain/kotlin/dev/inmo/postssystem/features/roles/server/RolesChecker.kt b/features/roles/server/src/jvmMain/kotlin/dev/inmo/postssystem/features/roles/server/RolesChecker.kt index 6e1bd406..b6e118b3 100644 --- a/features/roles/server/src/jvmMain/kotlin/dev/inmo/postssystem/features/roles/server/RolesChecker.kt +++ b/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 { +interface RolesChecker { val key: String suspend operator fun ApplicationCall.invoke( - usersRolesStorage: ReadUsersRolesStorage, + usersRolesStorage: ReadRolesStorage, user: User ): Boolean companion object { - fun default( + fun default( key: String, - role: T - ): RolesChecker = object : RolesChecker { + role: Role + ): RolesChecker = object : RolesChecker { override val key: String get() = key override suspend fun ApplicationCall.invoke( - usersRolesStorage: ReadUsersRolesStorage, + usersRolesStorage: ReadRolesStorage, user: User ): Boolean = usersRolesStorage.contains(user.id, role) } diff --git a/features/roles/server/src/jvmMain/kotlin/dev/inmo/postssystem/features/roles/server/UsersRolesStorageWriteServerRoutesConfigurator.kt b/features/roles/server/src/jvmMain/kotlin/dev/inmo/postssystem/features/roles/server/RolesStorageWriteServerRoutesConfigurator.kt similarity index 78% rename from features/roles/server/src/jvmMain/kotlin/dev/inmo/postssystem/features/roles/server/UsersRolesStorageWriteServerRoutesConfigurator.kt rename to features/roles/server/src/jvmMain/kotlin/dev/inmo/postssystem/features/roles/server/RolesStorageWriteServerRoutesConfigurator.kt index c87fdd61..9da02867 100644 --- a/features/roles/server/src/jvmMain/kotlin/dev/inmo/postssystem/features/roles/server/UsersRolesStorageWriteServerRoutesConfigurator.kt +++ b/features/roles/server/src/jvmMain/kotlin/dev/inmo/postssystem/features/roles/server/RolesStorageWriteServerRoutesConfigurator.kt @@ -9,19 +9,19 @@ import io.ktor.routing.* import kotlinx.serialization.KSerializer import kotlinx.serialization.builtins.serializer -class UsersRolesStorageWriteServerRoutesConfigurator( - private val storage: WriteUsersRolesStorage, +class RolesStorageWriteServerRoutesConfigurator( + private val storage: WriteRolesStorage, private val serializer: KSerializer, 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( unianswer( Boolean.serializer(), storage.include( - wrapper.userId, + wrapper.subject, wrapper.userRole ) ) @@ -42,7 +42,7 @@ class UsersRolesStorageWriteServerRoutesConfigurator( unianswer( Boolean.serializer(), storage.exclude( - wrapper.userId, + wrapper.subject, wrapper.userRole ) ) diff --git a/features/roles/server/src/jvmMain/kotlin/dev/inmo/postssystem/features/roles/server/UsersRolesAggregator.kt b/features/roles/server/src/jvmMain/kotlin/dev/inmo/postssystem/features/roles/server/UsersRolesAggregator.kt index 8843c789..52738bc1 100644 --- a/features/roles/server/src/jvmMain/kotlin/dev/inmo/postssystem/features/roles/server/UsersRolesAggregator.kt +++ b/features/roles/server/src/jvmMain/kotlin/dev/inmo/postssystem/features/roles/server/UsersRolesAggregator.kt @@ -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> -) : UsersRolesStorage { +class RolesAggregator( + private val otherStorages: List> +) : RolesStorage { private val otherStoragesByClass = otherStorages.associateBy { it.kclass } - override suspend fun getUsers(userRole: UserRole): List { - return otherStoragesByClass[userRole::class] ?.getUsers(userRole) ?: emptyList() + override suspend fun getSubjects(role: Role): List { + return otherStoragesByClass[role::class] ?.getUsers(role) ?: emptyList() } - override suspend fun getRoles(userId: UserId): List = otherStorages.flatMap { it.getRoles(userId) } + override suspend fun getRoles(subject: RoleSubject): List = 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): Boolean { - return userRoles.any { - contains(userId, it) + override suspend fun containsAny(subject: RoleSubject, roles: List): 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 } } diff --git a/features/roles/server/src/jvmMain/kotlin/dev/inmo/postssystem/features/roles/server/UsersRolesAuthenticationConfigurator.kt b/features/roles/server/src/jvmMain/kotlin/dev/inmo/postssystem/features/roles/server/UsersRolesAuthenticationConfigurator.kt index a38eaae6..02ce53b8 100644 --- a/features/roles/server/src/jvmMain/kotlin/dev/inmo/postssystem/features/roles/server/UsersRolesAuthenticationConfigurator.kt +++ b/features/roles/server/src/jvmMain/kotlin/dev/inmo/postssystem/features/roles/server/UsersRolesAuthenticationConfigurator.kt @@ -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( - private val usersRolesStorage: UsersRolesStorage, +class RolesAuthenticationConfigurator( + private val usersRolesStorage: RolesStorage, private val authTokensService: AuthTokensService, - private val rolesCheckers: List>, + private val rolesCheckers: List> ) : ApplicationAuthenticationConfigurator.Element { override fun Authentication.Configuration.invoke() { rolesCheckers.forEach { checker -> diff --git a/features/roles/server/src/jvmMain/kotlin/dev/inmo/postssystem/features/roles/server/UsersRolesStorageHolder.kt b/features/roles/server/src/jvmMain/kotlin/dev/inmo/postssystem/features/roles/server/UsersRolesStorageHolder.kt index dbd0e878..532f82dc 100644 --- a/features/roles/server/src/jvmMain/kotlin/dev/inmo/postssystem/features/roles/server/UsersRolesStorageHolder.kt +++ b/features/roles/server/src/jvmMain/kotlin/dev/inmo/postssystem/features/roles/server/UsersRolesStorageHolder.kt @@ -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( +data class RolesStorageHolder( val kclass: KClass, - val storage: UsersRolesStorage + val storage: RolesStorage ) { private suspend fun doIfRelevant( - userRole: UserRole, + role: Role, block: suspend (T) -> R - ): Optional = if (kclass.isInstance(userRole)) { - block(userRole as T).optional + ): Optional = if (kclass.isInstance(role)) { + block(role as T).optional } else { Optional.absent() } - suspend fun getUsers(userRole: UserRole): List? = doIfRelevant(userRole) { - storage.getUsers(it) + suspend fun getUsers(role: Role): List? = doIfRelevant(role) { + storage.getSubjects(it) }.dataOrNull() - suspend fun getRoles(userId: UserId): List = storage.getRoles(userId) + suspend fun getRoles(subject: RoleSubject): List = 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() } diff --git a/features/roles/server/src/jvmMain/kotlin/dev/inmo/postssystem/features/roles/server/UsersRolesStorageReadServerRoutesConfigurator.kt b/features/roles/server/src/jvmMain/kotlin/dev/inmo/postssystem/features/roles/server/UsersRolesStorageReadServerRoutesConfigurator.kt index 33a6219f..24440239 100644 --- a/features/roles/server/src/jvmMain/kotlin/dev/inmo/postssystem/features/roles/server/UsersRolesStorageReadServerRoutesConfigurator.kt +++ b/features/roles/server/src/jvmMain/kotlin/dev/inmo/postssystem/features/roles/server/UsersRolesStorageReadServerRoutesConfigurator.kt @@ -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( - private val storage: ReadUsersRolesStorage, +class RolesStorageReadServerRoutesConfigurator( + private val storage: ReadRolesStorage, private val serializer: KSerializer, private val unifiedRouter: UnifiedRouter ) : ApplicationRoutingConfigurator.Element { @@ -21,51 +19,53 @@ class UsersRolesStorageReadServerRoutesConfigurator( 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) ) } } diff --git a/mppJavaProject.gradle b/mppJavaProject.gradle index d006f30b..2039c0f2 100644 --- a/mppJavaProject.gradle +++ b/mppJavaProject.gradle @@ -1,7 +1,7 @@ project.version = "$version" project.group = "$group" - apply from: "$publishGradlePath" +apply from: "$publishGradlePath" kotlin { jvm().compilations.main { @@ -31,3 +31,8 @@ kotlin { } } } + +java { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 +} diff --git a/mppJsProject.gradle b/mppJsProject.gradle index 761487a3..cbb2cc45 100644 --- a/mppJsProject.gradle +++ b/mppJsProject.gradle @@ -1,7 +1,7 @@ project.version = "$version" project.group = "$group" - apply from: "$publishGradlePath" +apply from: "$publishGradlePath" kotlin { js (IR) { diff --git a/mppProjectWithSerialization.gradle b/mppProjectWithSerialization.gradle index 864b3dff..35215f12 100644 --- a/mppProjectWithSerialization.gradle +++ b/mppProjectWithSerialization.gradle @@ -1,7 +1,7 @@ project.version = "$version" project.group = "$group" - apply from: "$publishGradlePath" +apply from: "$publishGradlePath" kotlin { jvm().compilations.main { @@ -53,3 +53,8 @@ kotlin { } apply from: "$defaultAndroidSettingsPresetPath" + +java { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 +} diff --git a/server/src/main/java/dev/inmo/postssystem/server/DI.kt b/server/src/main/java/dev/inmo/postssystem/server/DI.kt index e36595e4..84a7ac1b 100644 --- a/server/src/main/java/dev/inmo/postssystem/server/DI.kt +++ b/server/src/main/java/dev/inmo/postssystem/server/DI.kt @@ -9,17 +9,16 @@ import dev.inmo.postssystem.features.files.common.storage.* import dev.inmo.postssystem.features.files.common.storage.WriteFilesStorage import dev.inmo.postssystem.features.files.server.FilesRoutingConfigurator import dev.inmo.postssystem.features.roles.common.* -import dev.inmo.postssystem.features.roles.common.keyvalue.KeyValuesUsersRolesOriginalRepo +import dev.inmo.postssystem.features.roles.common.keyvalue.KeyValuesRolesOriginalRepo import dev.inmo.postssystem.features.roles.manager.common.RolesManagerRole import dev.inmo.postssystem.features.roles.manager.common.RolesManagerRoleStorage import dev.inmo.postssystem.features.roles.manager.server.RolesManagerRolesChecker -import dev.inmo.postssystem.features.roles.manager.server.RolesManagerUsersRolesStorageServerRoutesConfigurator +import dev.inmo.postssystem.features.roles.manager.server.RolesManagerRolesStorageServerRoutesConfigurator import dev.inmo.postssystem.features.roles.server.* import dev.inmo.postssystem.features.status.server.StatusRoutingConfigurator import dev.inmo.postssystem.features.users.common.ExposedUsersStorage import dev.inmo.postssystem.features.users.server.UsersStorageServerRoutesConfigurator import dev.inmo.micro_utils.coroutines.LinkedSupervisorScope -import dev.inmo.micro_utils.ktor.common.standardKtorSerialFormat import dev.inmo.micro_utils.ktor.server.UnifiedRouter import dev.inmo.micro_utils.ktor.server.configurators.* import dev.inmo.micro_utils.ktor.server.createKtorServer @@ -113,23 +112,23 @@ fun getDIModule( singleWithBinds { ExposedUsersStorage(get()) } singleWithBinds { exposedUsersAuthenticator(get(), get()) } - factory(usersRolesKeyValueFactoryQualifier) { (tableName: String) -> - ExposedOneToManyKeyValueRepo(get(), { long("userId") }, { text("role") }, tableName) + factory(usersRolesKeyValueFactoryQualifier) { (tableName: String) -> + ExposedOneToManyKeyValueRepo(get(), { text("subject") }, { text("role") }, tableName) } single { RolesManagerRoleStorage(get(usersRolesKeyValueFactoryQualifier) { ParametersHolder(mutableListOf("rolesManager")) }) } - single>(StringQualifier("RolesManagerRoleStorage")) { get() } + single>(StringQualifier("RolesManagerRoleStorage")) { get() } singleWithBinds { - UsersRolesStorageHolder( + RolesStorageHolder( RolesManagerRole::class, get() ) } - singleWithBinds> { UsersRolesAggregator(getAll()) } + singleWithBinds> { RolesAggregator(getAll()) } // Roles checkers - single>(StringQualifier(RolesManagerRolesChecker.key)) { RolesManagerRolesChecker } + single>(StringQualifier(RolesManagerRolesChecker.key)) { RolesManagerRolesChecker } factory { baseScope.LinkedSupervisorScope() } @@ -137,12 +136,12 @@ fun getDIModule( singleWithBinds { FilesRoutingConfigurator(get(), null, get()) } singleWithBinds { StatusRoutingConfigurator } singleWithBinds { UsersStorageServerRoutesConfigurator(get(), get()) } - singleWithBinds { UsersRolesStorageReadServerRoutesConfigurator(get(), UserRoleSerializer, get()) } - singleWithBinds { RolesManagerUsersRolesStorageServerRoutesConfigurator(get(), get()) } + singleWithBinds { RolesStorageReadServerRoutesConfigurator(get(), RoleSerializer, get()) } + singleWithBinds { RolesManagerRolesStorageServerRoutesConfigurator(get(), get()) } singleWithBinds { ClientStaticRoutingConfiguration(get().clientStatic) } singleWithBinds { - UsersRolesAuthenticationConfigurator( + RolesAuthenticationConfigurator( get(), get(), getAll()