修复权限取消,同时在取消时给出更多提示 (#1843)

* fix: AbstractConcurrentPermissionService

* feat: cancel about

* fix: filter parent

* fix: return

* fix: filter parent

* add: PermissionServiceTest
This commit is contained in:
cssxsh 2022-02-22 18:34:18 +08:00 committed by GitHub
parent 29ebf78a54
commit 5a1059b0b3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 97 additions and 14 deletions

View File

@ -11,17 +11,14 @@ package net.mamoe.mirai.console.internal.permission
import net.mamoe.mirai.console.data.PluginDataExtensions
import net.mamoe.mirai.console.permission.*
import net.mamoe.mirai.console.permission.Permission.Companion.parentsWithSelf
import net.mamoe.mirai.console.permission.PermitteeId.Companion.hasChild
internal abstract class AbstractConcurrentPermissionService<P : Permission> : PermissionService<P> {
protected abstract val permissions: MutableMap<PermissionId, P>
protected abstract val grantedPermissionsMap: PluginDataExtensions.NotNullMutableMap<PermissionId, MutableCollection<PermitteeId>>
protected abstract fun createPermission(
id: PermissionId,
description: String,
parent: Permission
): P
protected abstract fun createPermission(id: PermissionId, description: String, parent: Permission): P
override fun get(id: PermissionId): P? = permissions[id]
@ -33,23 +30,47 @@ internal abstract class AbstractConcurrentPermissionService<P : Permission> : Pe
}
override fun permit(permitteeId: PermitteeId, permission: P) {
val id = permission.id
grantedPermissionsMap[id].add(permitteeId)
grantedPermissionsMap[permission.id].add(permitteeId)
}
override fun cancel(permitteeId: PermitteeId, permission: P, recursive: Boolean) {
if (recursive) {
grantedPermissionsMap[permission.id]
} else grantedPermissionsMap[permission.id].remove(permitteeId)
val success = if (recursive) {
getPermittedPermissions(permitteeId).any { permitted ->
(permission in permitted.parentsWithSelf) && grantedPermissionsMap[permitted.id].remove(permitteeId)
}
} else {
grantedPermissionsMap[permission.id].remove(permitteeId)
}
check(success) {
val about = buildList {
for ((permissionIdentifier, permissibleIdentifiers) in grantedPermissionsMap) {
val parent = get(permissionIdentifier) ?: continue
if (parent !in permission.parentsWithSelf) continue
for (permissibleId in permissibleIdentifiers) {
if (permitteeId.hasChild(permitteeId)) {
add(parent to permissibleId)
}
}
}
}
if (about.isEmpty()) {
"${permitteeId.asString()} 不拥有权限 ${permission.id} "
} else {
"""
${permitteeId.asString()} ${permission.id} 权限来自
${about.joinToString("\n") { (parent, permitted) -> "${permitted.asString()} ${parent.id}" }}
Mirai Console 内置权限系统目前不支持单独禁用继承得到的权限. 可取消继承来源再为其分别分配.
""".trimIndent()
}
}
}
override fun getRegisteredPermissions(): Sequence<P> = permissions.values.asSequence()
override fun getPermittedPermissions(permitteeId: PermitteeId): Sequence<P> = sequence<P> {
override fun getPermittedPermissions(permitteeId: PermitteeId): Sequence<P> = sequence {
for ((permissionIdentifier, permissibleIdentifiers) in grantedPermissionsMap) {
val granted =
if (permissibleIdentifiers.isEmpty()) false
else permissibleIdentifiers.any { permitteeId.hasChild(it) }
val granted = permissibleIdentifiers.any { permitteeId.hasChild(it) }
if (granted) get(permissionIdentifier)?.let { yield(it) }
}

View File

@ -0,0 +1,62 @@
/*
* Copyright 2019-2022 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
package net.mamoe.mirai.console.permission
import net.mamoe.mirai.console.internal.permission.BuiltInPermissionService
import net.mamoe.mirai.console.internal.permission.PermissionImpl
import org.junit.jupiter.api.Test
import kotlin.test.*
internal class PermissionServiceTest {
@Test
fun `test built in`() {
val builtIn: PermissionService<PermissionImpl> = BuiltInPermissionService()
assertEquals(PermissionId.parseFromString("*:*"), builtIn.rootPermission.id)
val plugin = builtIn.register(PermissionId.parseFromString("plugin:*"), "", builtIn.rootPermission)
assertEquals(builtIn[PermissionId.parseFromString("plugin:*")], plugin)
val command = builtIn.register(PermissionId.parseFromString("plugin:command"), "", plugin)
assertEquals(builtIn[PermissionId.parseFromString("plugin:command")], command)
val any = AbstractPermitteeId.parseFromString("m12345.*")
val member = AbstractPermitteeId.parseFromString("m12345.6789")
assertFalse { builtIn.testPermission(any, plugin) }
// test permit
builtIn.permit(any, plugin)
assertTrue { builtIn.testPermission(any, plugin) }
assertTrue { builtIn.testPermission(member, plugin) }
assertTrue { builtIn.testPermission(any, command) }
assertTrue { builtIn.testPermission(member, command) }
assertFails { builtIn.cancel(member, command, false) }
// test recursive cancel
builtIn.cancel(any, builtIn.rootPermission, true)
assertFalse { builtIn.testPermission(any, plugin) }
assertFalse { builtIn.testPermission(member, plugin) }
assertFalse { builtIn.testPermission(any, command) }
assertFalse { builtIn.testPermission(member, command) }
// test not recursive cancel
builtIn.permit(any, plugin)
builtIn.permit(any, command)
builtIn.cancel(any, plugin, false)
assertFalse { builtIn.testPermission(any, plugin) }
assertFalse { builtIn.testPermission(member, plugin) }
assertTrue { builtIn.testPermission(any, command) }
assertTrue { builtIn.testPermission(member, command) }
assertFails { builtIn.cancel(member, command, false) }
}
}