mirror of
https://github.com/mamoe/mirai.git
synced 2025-03-03 15:10:14 +08:00
Improve LoginCommand logic, remove unsafe checks, and add tests
This commit is contained in:
parent
b1d66c0d20
commit
366ea34fde
@ -50,6 +50,9 @@ import net.mamoe.mirai.console.util.*
|
||||
import net.mamoe.mirai.event.events.EventCancelledException
|
||||
import net.mamoe.mirai.message.nextMessageOrNull
|
||||
import net.mamoe.mirai.utils.BotConfiguration
|
||||
import net.mamoe.mirai.utils.Either
|
||||
import net.mamoe.mirai.utils.Either.Companion.flatMapNull
|
||||
import net.mamoe.mirai.utils.Either.Companion.fold
|
||||
import net.mamoe.mirai.utils.MiraiLogger
|
||||
import net.mamoe.mirai.utils.secondsToMillis
|
||||
import java.lang.management.ManagementFactory
|
||||
@ -188,9 +191,12 @@ public object BuiltInCommands {
|
||||
ConsoleCommandOwner, "login", "登录",
|
||||
description = "登录一个账号",
|
||||
), BuiltInCommandInternal {
|
||||
private suspend fun Bot.doLogin() = kotlin.runCatching {
|
||||
login(); this
|
||||
}.onFailure { close() }.getOrThrow()
|
||||
internal var doLogin: suspend Bot.() -> Bot = {
|
||||
kotlin.runCatching {
|
||||
login()
|
||||
this
|
||||
}.onFailure { close() }.getOrThrow()
|
||||
} // workaround since LoginCommand is object
|
||||
|
||||
@Handler
|
||||
@JvmOverloads
|
||||
@ -204,24 +210,27 @@ public object BuiltInCommands {
|
||||
return this
|
||||
}
|
||||
|
||||
suspend fun getPassword(id: Long): Any? {
|
||||
fun getPassword(id: Long): Either<ByteArray, String?> {
|
||||
val config = DataScope.get<AutoLoginConfig>()
|
||||
val acc = config.accounts.firstOrNull { it.account == id.toString() }
|
||||
if (acc == null) {
|
||||
sendMessage("Could not find '$id' in AutoLogin config. Please specify password.")
|
||||
return null
|
||||
}
|
||||
val acc = config.accounts.firstOrNull { it.account == id.toString() } ?: return Either.right(null)
|
||||
val strv = acc.password.value
|
||||
return if (acc.password.kind == MD5) strv.autoHexToBytes() else strv
|
||||
return if (acc.password.kind == MD5) Either.left(strv.autoHexToBytes()) else Either.right(strv)
|
||||
}
|
||||
|
||||
val pwd: Any = password ?: getPassword(id) ?: return
|
||||
val pwd = Either.right<ByteArray, String?>(password).flatMapNull { getPassword(id) }
|
||||
kotlin.runCatching {
|
||||
when (pwd) {
|
||||
is String -> MiraiConsole.addBot(id, pwd) { setup(protocol) }.doLogin()
|
||||
is ByteArray -> MiraiConsole.addBot(id, pwd) { setup(protocol) }.doLogin()
|
||||
else -> throw AssertionError("Assertion failed, please report to https://github.com/mamoe/mirai-console/issues/new/choose, debug=${pwd.javaClass}")// Unreachable
|
||||
}
|
||||
pwd.fold(
|
||||
onLeft = { pass ->
|
||||
MiraiConsole.addBot(id, pass) { setup(protocol) }.doLogin()
|
||||
},
|
||||
onRight = { pass ->
|
||||
if (pass == null) {
|
||||
sendMessage("Could not find '$id' in AutoLogin config. Please specify password.")
|
||||
return
|
||||
}
|
||||
MiraiConsole.addBot(id, pass) { setup(protocol) }.doLogin()
|
||||
}
|
||||
)
|
||||
}.fold(
|
||||
onSuccess = { scopeWith(ConsoleCommandSender).sendMessage("${it.nick} ($id) Login successful") },
|
||||
onFailure = { throwable ->
|
||||
|
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* 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.command
|
||||
|
||||
import net.mamoe.mirai.console.internal.data.builtins.ConsoleDataScopeImpl
|
||||
import net.mamoe.mirai.console.internal.data.builtins.DataScope
|
||||
import net.mamoe.mirai.console.testFramework.AbstractConsoleInstanceTest
|
||||
|
||||
internal abstract class AbstractCommandTest : AbstractConsoleInstanceTest() {
|
||||
val dataScope get() = DataScope as ConsoleDataScopeImpl
|
||||
val consoleSender get() = ConsoleCommandSender
|
||||
}
|
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
@file:Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
|
||||
|
||||
package net.mamoe.mirai.console.command
|
||||
|
||||
import kotlinx.coroutines.CompletableDeferred
|
||||
import me.him188.kotlin.jvm.blocking.bridge.JvmBlockingBridge
|
||||
import net.mamoe.mirai.console.command.BuiltInCommands.LoginCommand
|
||||
import net.mamoe.mirai.console.command.descriptor.ExperimentalCommandDescriptors
|
||||
import net.mamoe.mirai.console.internal.data.builtins.AutoLoginConfig
|
||||
import net.mamoe.mirai.console.internal.data.builtins.AutoLoginConfig.Account
|
||||
import net.mamoe.mirai.console.internal.data.builtins.AutoLoginConfig.Account.PasswordKind
|
||||
import net.mamoe.mirai.utils.md5
|
||||
import net.mamoe.mirai.utils.toUHexString
|
||||
import org.junit.jupiter.api.Test
|
||||
import kotlin.test.assertContentEquals
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@OptIn(ExperimentalCommandDescriptors::class)
|
||||
@JvmBlockingBridge
|
||||
internal class LoginCommandTest : AbstractCommandTest() {
|
||||
|
||||
@Test
|
||||
suspend fun `login with provided password`() {
|
||||
val myId = 123L
|
||||
val myPwd = "password001"
|
||||
|
||||
val bot = awaitDeferred<net.mamoe.mirai.internal.QQAndroidBot> { cont ->
|
||||
LoginCommand.doLogin = {
|
||||
val bot = bot as net.mamoe.mirai.internal.QQAndroidBot
|
||||
cont.complete(bot)
|
||||
bot
|
||||
}
|
||||
|
||||
LoginCommand.execute(consoleSender, "$myId $myPwd")
|
||||
}
|
||||
|
||||
val account = bot.account
|
||||
assertContentEquals(myPwd.md5(), account.passwordMd5)
|
||||
assertEquals(myId, account.id)
|
||||
}
|
||||
|
||||
@Test
|
||||
suspend fun `login with saved plain password`() {
|
||||
val myId = 123L
|
||||
val myPwd = "password001"
|
||||
|
||||
dataScope.set(AutoLoginConfig().apply {
|
||||
accounts.add(
|
||||
Account(
|
||||
account = myId.toString(),
|
||||
password = Account.Password(PasswordKind.PLAIN, myPwd)
|
||||
)
|
||||
)
|
||||
})
|
||||
|
||||
val bot = awaitDeferred<net.mamoe.mirai.internal.QQAndroidBot> { cont ->
|
||||
LoginCommand.doLogin = {
|
||||
val bot = bot as net.mamoe.mirai.internal.QQAndroidBot
|
||||
cont.complete(bot)
|
||||
bot
|
||||
}
|
||||
|
||||
LoginCommand.execute(consoleSender, "$myId")
|
||||
}
|
||||
|
||||
val account = bot.account
|
||||
assertContentEquals(myPwd.md5(), account.passwordMd5)
|
||||
assertEquals(myId, account.id)
|
||||
}
|
||||
|
||||
@Test
|
||||
suspend fun `login with saved md5 password`() {
|
||||
val myId = 123L
|
||||
val myPwd = "password001"
|
||||
|
||||
dataScope.set(AutoLoginConfig().apply {
|
||||
accounts.add(
|
||||
Account(
|
||||
account = myId.toString(),
|
||||
password = Account.Password(PasswordKind.MD5, myPwd.md5().toUHexString(""))
|
||||
)
|
||||
)
|
||||
})
|
||||
|
||||
val bot = awaitDeferred<net.mamoe.mirai.internal.QQAndroidBot> { cont ->
|
||||
LoginCommand.doLogin = {
|
||||
val bot = bot as net.mamoe.mirai.internal.QQAndroidBot
|
||||
cont.complete(bot)
|
||||
bot
|
||||
}
|
||||
|
||||
LoginCommand.execute(consoleSender, "$myId")
|
||||
}
|
||||
|
||||
val account = bot.account
|
||||
assertContentEquals(myPwd.md5(), account.passwordMd5)
|
||||
assertEquals(myId, account.id)
|
||||
}
|
||||
}
|
||||
|
||||
@BuilderInference
|
||||
internal suspend inline fun <T> awaitDeferred(
|
||||
@BuilderInference
|
||||
crossinline block: suspend (CompletableDeferred<T>) -> Unit
|
||||
): T {
|
||||
val deferred = CompletableDeferred<T>()
|
||||
block(deferred)
|
||||
return deferred.await()
|
||||
}
|
Loading…
Reference in New Issue
Block a user