Review PermissionService

This commit is contained in:
Him188 2020-10-25 20:59:56 +08:00
parent 291035f978
commit 1f790158e6
3 changed files with 128 additions and 24 deletions

View File

@ -25,10 +25,10 @@ import net.mamoe.mirai.console.internal.command.CommandManagerImpl.allRegistered
import net.mamoe.mirai.console.internal.util.runIgnoreException import net.mamoe.mirai.console.internal.util.runIgnoreException
import net.mamoe.mirai.console.permission.Permission import net.mamoe.mirai.console.permission.Permission
import net.mamoe.mirai.console.permission.PermissionService import net.mamoe.mirai.console.permission.PermissionService
import net.mamoe.mirai.console.permission.PermissionService.Companion.denyPermission import net.mamoe.mirai.console.permission.PermissionService.Companion.cancel
import net.mamoe.mirai.console.permission.PermissionService.Companion.findCorrespondingPermissionOrFail import net.mamoe.mirai.console.permission.PermissionService.Companion.findCorrespondingPermissionOrFail
import net.mamoe.mirai.console.permission.PermissionService.Companion.getPermittedPermissions import net.mamoe.mirai.console.permission.PermissionService.Companion.getPermittedPermissions
import net.mamoe.mirai.console.permission.PermissionService.Companion.grantPermission import net.mamoe.mirai.console.permission.PermissionService.Companion.permit
import net.mamoe.mirai.console.permission.PermitteeId import net.mamoe.mirai.console.permission.PermitteeId
import net.mamoe.mirai.console.util.ConsoleExperimentalApi import net.mamoe.mirai.console.util.ConsoleExperimentalApi
import net.mamoe.mirai.console.util.ConsoleInternalApi import net.mamoe.mirai.console.util.ConsoleInternalApi
@ -170,7 +170,7 @@ public object BuiltInCommands {
@Name("被许可人 ID") target: PermitteeId, @Name("被许可人 ID") target: PermitteeId,
@Name("权限 ID") permission: Permission, @Name("权限 ID") permission: Permission,
) { ) {
target.grantPermission(permission) target.permit(permission)
sendMessage("OK") sendMessage("OK")
} }
@ -180,7 +180,7 @@ public object BuiltInCommands {
@Name("被许可人 ID") target: PermitteeId, @Name("被许可人 ID") target: PermitteeId,
@Name("权限 ID") permission: Permission, @Name("权限 ID") permission: Permission,
) { ) {
target.denyPermission(permission, false) target.cancel(permission, false)
sendMessage("OK") sendMessage("OK")
} }
@ -190,7 +190,7 @@ public object BuiltInCommands {
@Name("被许可人 ID") target: PermitteeId, @Name("被许可人 ID") target: PermitteeId,
@Name("权限 ID") permission: Permission, @Name("权限 ID") permission: Permission,
) { ) {
target.denyPermission(permission, true) target.cancel(permission, true)
sendMessage("OK") sendMessage("OK")
} }

View File

@ -38,7 +38,7 @@ import net.mamoe.mirai.console.internal.permission.BuiltInPermissionService
import net.mamoe.mirai.console.internal.plugin.PluginManagerImpl import net.mamoe.mirai.console.internal.plugin.PluginManagerImpl
import net.mamoe.mirai.console.internal.util.autoHexToBytes import net.mamoe.mirai.console.internal.util.autoHexToBytes
import net.mamoe.mirai.console.permission.PermissionService import net.mamoe.mirai.console.permission.PermissionService
import net.mamoe.mirai.console.permission.PermissionService.Companion.grantPermission import net.mamoe.mirai.console.permission.PermissionService.Companion.permit
import net.mamoe.mirai.console.permission.RootPermission import net.mamoe.mirai.console.permission.RootPermission
import net.mamoe.mirai.console.plugin.PluginManager import net.mamoe.mirai.console.plugin.PluginManager
import net.mamoe.mirai.console.plugin.center.PluginCenter import net.mamoe.mirai.console.plugin.center.PluginCenter
@ -174,7 +174,7 @@ internal object MiraiConsoleImplementationBridge : CoroutineScope, MiraiConsoleI
} }
} }
ConsoleCommandSender.grantPermission(RootPermission) ConsoleCommandSender.permit(RootPermission)
} }
phase `prepare commands`@{ phase `prepare commands`@{

View File

@ -27,7 +27,7 @@ import kotlin.reflect.KClass
* ### 可扩展 * ### 可扩展
* 权限服务可由插件扩展并覆盖默认实现. * 权限服务可由插件扩展并覆盖默认实现.
* *
* [PermissionServiceProvider] * @see PermissionServiceProvider 相应扩展
*/ */
@PermissionImplementation @PermissionImplementation
public interface PermissionService<P : Permission> { public interface PermissionService<P : Permission> {
@ -50,11 +50,15 @@ public interface PermissionService<P : Permission> {
/** /**
* 获取所有已注册的指令列表. 应保证线程安全. * 获取所有已注册的指令列表. 应保证线程安全.
*
* 备注: Java 实现者使用 `CollectionsKt.asSequence(Collection)` 构造 [Sequence]
*/ */
public fun getRegisteredPermissions(): Sequence<P> public fun getRegisteredPermissions(): Sequence<P>
/** /**
* 获取 [PermitteeId] 和其父标识的所有被授予的所有直接和间接的权限列表 * 获取 [PermitteeId] 和其父标识的所有被授予的所有直接和间接的权限列表
*
* 备注: Java 实现者使用 `CollectionsKt.asSequence(Collection)` 构造 [Sequence]
*/ */
public fun getPermittedPermissions(permitteeId: PermitteeId): Sequence<P> public fun getPermittedPermissions(permitteeId: PermitteeId): Sequence<P>
@ -83,7 +87,12 @@ public interface PermissionService<P : Permission> {
* *
* @throws PermissionRegistryConflictException 当已存在一个 [PermissionId] 时抛出. * @throws PermissionRegistryConflictException 当已存在一个 [PermissionId] 时抛出.
* *
* @param description 描述. 将会展示给用户.
*
* @return 申请到的 [Permission] 实例 * @return 申请到的 [Permission] 实例
*
* @see get 获取一个已注册的权限
* @see getOrFail 获取一个已注册的权限
*/ */
@Throws(PermissionRegistryConflictException::class) @Throws(PermissionRegistryConflictException::class)
public fun register( public fun register(
@ -97,7 +106,10 @@ public interface PermissionService<P : Permission> {
public fun allocatePermissionIdForPlugin( public fun allocatePermissionIdForPlugin(
plugin: Plugin, plugin: Plugin,
@ResolveContext(COMMAND_NAME) permissionName: String, @ResolveContext(COMMAND_NAME) permissionName: String,
): PermissionId = allocatePermissionIdForPluginDefaultImplement(plugin, permissionName) ): PermissionId = PermissionId(
plugin.description.id.toLowerCase(),
permissionName.toLowerCase()
)
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
@ -129,6 +141,9 @@ public interface PermissionService<P : Permission> {
public companion object { public companion object {
internal var instanceField: PermissionService<*>? = null internal var instanceField: PermissionService<*>? = null
/**
* [PermissionService] 实例
*/
@get:JvmName("getInstance") @get:JvmName("getInstance")
@JvmStatic @JvmStatic
public val INSTANCE: PermissionService<out Permission> public val INSTANCE: PermissionService<out Permission>
@ -136,82 +151,171 @@ public interface PermissionService<P : Permission> {
/** /**
* 获取一个权限, 失败时抛出 [NoSuchElementException] * 获取一个权限, 失败时抛出 [NoSuchElementException]
*
* @see register 申请并注册一个权限
*/ */
@JvmStatic
@Throws(NoSuchElementException::class) @Throws(NoSuchElementException::class)
public fun <P : Permission> PermissionService<P>.getOrFail(id: PermissionId): P = public fun <P : Permission> PermissionService<P>.getOrFail(id: PermissionId): P =
get(id) ?: throw NoSuchElementException("Permission not found: $id") get(id) ?: throw NoSuchElementException("Permission not found: $id")
internal fun PermissionService<*>.allocatePermissionIdForPluginDefaultImplement( /**
plugin: Plugin, * @see findCorrespondingPermission
@ResolveContext(COMMAND_NAME) permissionName: String, */
) = PermissionId( @JvmStatic
plugin.description.id.toLowerCase(), public val PermissionId.correspondingPermission: Permission?
permissionName.toLowerCase() get() = findCorrespondingPermission()
)
/**
* @see get
*/
@JvmStatic
public fun PermissionId.findCorrespondingPermission(): Permission? = INSTANCE[this] public fun PermissionId.findCorrespondingPermission(): Permission? = INSTANCE[this]
/**
* @see getOrFail
* @throws NoSuchElementException
*/
@Throws(NoSuchElementException::class)
@JvmStatic
public fun PermissionId.findCorrespondingPermissionOrFail(): Permission = INSTANCE.getOrFail(this) public fun PermissionId.findCorrespondingPermissionOrFail(): Permission = INSTANCE.getOrFail(this)
public fun PermitteeId.grantPermission(permission: Permission) { /**
* @see PermissionService.permit
*/
@JvmStatic
@JvmName("permit0") // clash, not JvmSynthetic to allow possible calls from Java.
public fun PermitteeId.permit(permission: Permission) {
INSTANCE.checkType(permission::class).permit(this, permission) INSTANCE.checkType(permission::class).permit(this, permission)
} }
public fun PermitteeId.grantPermission(permissionId: PermissionId) { /**
grantPermission(permissionId.findCorrespondingPermissionOrFail()) * @see PermissionService.permit
* @throws NoSuchElementException
*/
@JvmStatic
@Throws(NoSuchElementException::class)
public fun PermitteeId.permit(permissionId: PermissionId) {
permit(permissionId.findCorrespondingPermissionOrFail())
} }
public fun PermitteeId.denyPermission(permission: Permission, recursive: Boolean) { /**
* @see PermissionService.cancel
*/
@JvmSynthetic
@JvmStatic
@JvmName("cancel0") // clash, not JvmSynthetic to allow possible calls from Java.
public fun PermitteeId.cancel(permission: Permission, recursive: Boolean) {
INSTANCE.checkType(permission::class).cancel(this, permission, recursive) INSTANCE.checkType(permission::class).cancel(this, permission, recursive)
} }
public fun PermitteeId.denyPermission(permissionId: PermissionId, recursive: Boolean) { /**
denyPermission(permissionId.findCorrespondingPermissionOrFail(), recursive) * @see PermissionService.cancel
* @throws NoSuchElementException
*/
@JvmStatic
@Throws(NoSuchElementException::class)
public fun PermitteeId.cancel(permissionId: PermissionId, recursive: Boolean) {
cancel(permissionId.findCorrespondingPermissionOrFail(), recursive)
} }
/**
* @see PermissionService.testPermission
*/
@JvmStatic
public fun Permittee.hasPermission(permission: Permission): Boolean = public fun Permittee.hasPermission(permission: Permission): Boolean =
permission.testPermission(this@hasPermission) permission.testPermission(this@hasPermission)
/**
* @see PermissionService.testPermission
*/
@JvmStatic
public fun PermitteeId.hasPermission(permission: Permission): Boolean = public fun PermitteeId.hasPermission(permission: Permission): Boolean =
permission.testPermission(this@hasPermission) permission.testPermission(this@hasPermission)
/**
* @see PermissionService.testPermission
* @throws NoSuchElementException
*/
@JvmStatic
@Throws(NoSuchElementException::class)
public fun PermitteeId.hasPermission(permissionId: PermissionId): Boolean { public fun PermitteeId.hasPermission(permissionId: PermissionId): Boolean {
val instance = permissionId.findCorrespondingPermissionOrFail() val instance = permissionId.findCorrespondingPermissionOrFail()
return INSTANCE.checkType(instance::class).testPermission(this@hasPermission, instance) return INSTANCE.checkType(instance::class).testPermission(this@hasPermission, instance)
} }
/**
* @see PermissionService.testPermission
*/
@JvmStatic
public fun Permittee.hasPermission(permissionId: PermissionId): Boolean = public fun Permittee.hasPermission(permissionId: PermissionId): Boolean =
permissionId.testPermission(this@hasPermission) permissionId.testPermission(this@hasPermission)
/**
* @see PermissionService.getPermittedPermissions
*/
@JvmStatic
public fun Permittee.getPermittedPermissions(): Sequence<Permission> = public fun Permittee.getPermittedPermissions(): Sequence<Permission> =
INSTANCE.getPermittedPermissions(this@getPermittedPermissions.permitteeId) INSTANCE.getPermittedPermissions(this@getPermittedPermissions.permitteeId)
public fun Permittee.grantPermission(vararg permissions: Permission) {
/**
* @see PermissionService.permit
*/
@JvmStatic
public fun Permittee.permit(vararg permissions: Permission) {
for (permission in permissions) { for (permission in permissions) {
INSTANCE.checkType(permission::class).permit(this.permitteeId, permission) INSTANCE.checkType(permission::class).permit(this.permitteeId, permission)
} }
} }
public fun Permittee.denyPermission(vararg permissions: Permission, recursive: Boolean) { /**
* @see PermissionService.cancel
*/
@JvmStatic
public fun Permittee.cancel(vararg permissions: Permission, recursive: Boolean) {
for (permission in permissions) { for (permission in permissions) {
INSTANCE.checkType(permission::class).cancel(this.permitteeId, permission, recursive) INSTANCE.checkType(permission::class).cancel(this.permitteeId, permission, recursive)
} }
} }
/**
* @see PermissionService.getPermittedPermissions
*/
@JvmSynthetic
@JvmStatic
@JvmName("getPermittedPermissions0") // clash, not JvmSynthetic to allow possible calls from Java.
public fun PermitteeId.getPermittedPermissions(): Sequence<Permission> = public fun PermitteeId.getPermittedPermissions(): Sequence<Permission> =
INSTANCE.getPermittedPermissions(this@getPermittedPermissions) INSTANCE.getPermittedPermissions(this@getPermittedPermissions)
/**
* @see PermissionService.testPermission
*/
@JvmStatic
public fun Permission.testPermission(permittee: Permittee): Boolean = public fun Permission.testPermission(permittee: Permittee): Boolean =
INSTANCE.checkType(this::class).testPermission(permittee.permitteeId, this@testPermission) INSTANCE.checkType(this::class).testPermission(permittee.permitteeId, this@testPermission)
/**
* @see PermissionService.testPermission
*/
@JvmStatic
public fun Permission.testPermission(permitteeId: PermitteeId): Boolean = public fun Permission.testPermission(permitteeId: PermitteeId): Boolean =
INSTANCE.checkType(this::class).testPermission(permitteeId, this@testPermission) INSTANCE.checkType(this::class).testPermission(permitteeId, this@testPermission)
/**
* @see PermissionService.testPermission
*/
@JvmStatic
public fun PermissionId.testPermission(permittee: Permittee): Boolean { public fun PermissionId.testPermission(permittee: Permittee): Boolean {
val p = INSTANCE[this] ?: return false val p = INSTANCE[this] ?: return false
return p.testPermission(permittee) return p.testPermission(permittee)
} }
/**
* @see PermissionService.testPermission
*/
@JvmStatic
public fun PermissionId.testPermission(permissible: PermitteeId): Boolean { public fun PermissionId.testPermission(permissible: PermitteeId): Boolean {
val p = INSTANCE[this] ?: return false val p = INSTANCE[this] ?: return false
return p.testPermission(permissible) return p.testPermission(permissible)