mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-07 16:40:43 +08:00
Add tests for AccountSecrets
This commit is contained in:
parent
03a6596553
commit
d8819bd615
@ -18,7 +18,7 @@ import net.mamoe.mirai.internal.network.WLoginSigInfo
|
|||||||
import net.mamoe.mirai.internal.network.component.ComponentKey
|
import net.mamoe.mirai.internal.network.component.ComponentKey
|
||||||
import net.mamoe.mirai.internal.network.getRandomByteArray
|
import net.mamoe.mirai.internal.network.getRandomByteArray
|
||||||
import net.mamoe.mirai.internal.network.protocol.packet.login.wtlogin.get_mpasswd
|
import net.mamoe.mirai.internal.network.protocol.packet.login.wtlogin.get_mpasswd
|
||||||
import net.mamoe.mirai.internal.utils.actualCacheDir
|
import net.mamoe.mirai.internal.utils.accountSecretsFile
|
||||||
import net.mamoe.mirai.internal.utils.crypto.ECDHInitialPublicKey
|
import net.mamoe.mirai.internal.utils.crypto.ECDHInitialPublicKey
|
||||||
import net.mamoe.mirai.internal.utils.crypto.TEA
|
import net.mamoe.mirai.internal.utils.crypto.TEA
|
||||||
import net.mamoe.mirai.internal.utils.crypto.defaultInitialPublicKey
|
import net.mamoe.mirai.internal.utils.crypto.defaultInitialPublicKey
|
||||||
@ -77,7 +77,6 @@ internal interface AccountSecrets {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Suppress("ArrayInDataClass") // for `copy`
|
|
||||||
@Serializable
|
@Serializable
|
||||||
internal data class AccountSecretsImpl(
|
internal data class AccountSecretsImpl(
|
||||||
override var loginExtraData: MutableSet<LoginExtraData>,
|
override var loginExtraData: MutableSet<LoginExtraData>,
|
||||||
@ -89,7 +88,39 @@ internal data class AccountSecretsImpl(
|
|||||||
override var tgtgtKey: ByteArray,
|
override var tgtgtKey: ByteArray,
|
||||||
override val randomKey: ByteArray,
|
override val randomKey: ByteArray,
|
||||||
override var ecdhInitialPublicKey: ECDHInitialPublicKey,
|
override var ecdhInitialPublicKey: ECDHInitialPublicKey,
|
||||||
) : AccountSecrets, ProtoBuf
|
) : AccountSecrets, ProtoBuf {
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (this === other) return true
|
||||||
|
if (javaClass != other?.javaClass) return false
|
||||||
|
|
||||||
|
other as AccountSecretsImpl
|
||||||
|
|
||||||
|
if (loginExtraData != other.loginExtraData) return false
|
||||||
|
if (wLoginSigInfoField != other.wLoginSigInfoField) return false
|
||||||
|
if (!G.contentEquals(other.G)) return false
|
||||||
|
if (!dpwd.contentEquals(other.dpwd)) return false
|
||||||
|
if (!randSeed.contentEquals(other.randSeed)) return false
|
||||||
|
if (!ksid.contentEquals(other.ksid)) return false
|
||||||
|
if (!tgtgtKey.contentEquals(other.tgtgtKey)) return false
|
||||||
|
if (!randomKey.contentEquals(other.randomKey)) return false
|
||||||
|
if (ecdhInitialPublicKey != other.ecdhInitialPublicKey) return false
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
var result = loginExtraData.hashCode()
|
||||||
|
result = 31 * result + (wLoginSigInfoField?.hashCode() ?: 0)
|
||||||
|
result = 31 * result + G.contentHashCode()
|
||||||
|
result = 31 * result + dpwd.contentHashCode()
|
||||||
|
result = 31 * result + randSeed.contentHashCode()
|
||||||
|
result = 31 * result + ksid.contentHashCode()
|
||||||
|
result = 31 * result + tgtgtKey.contentHashCode()
|
||||||
|
result = 31 * result + randomKey.contentHashCode()
|
||||||
|
result = 31 * result + ecdhInitialPublicKey.hashCode()
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal fun AccountSecretsImpl(
|
internal fun AccountSecretsImpl(
|
||||||
other: AccountSecrets,
|
other: AccountSecrets,
|
||||||
@ -152,14 +183,7 @@ internal class FileCacheAccountSecretsManager(
|
|||||||
@Synchronized
|
@Synchronized
|
||||||
override fun saveSecrets(account: BotAccount, secrets: AccountSecrets) {
|
override fun saveSecrets(account: BotAccount, secrets: AccountSecrets) {
|
||||||
if (secrets.wLoginSigInfoField == null) return
|
if (secrets.wLoginSigInfoField == null) return
|
||||||
|
saveSecretsToFile(file, account, secrets)
|
||||||
file.writeBytes(
|
|
||||||
TEA.encrypt(
|
|
||||||
AccountSecretsImpl(secrets).toByteArray(AccountSecretsImpl.serializer()),
|
|
||||||
account.passwordMd5
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
logger.info { "Saved account secrets to local cache for fast login." }
|
logger.info { "Saved account secrets to local cache for fast login." }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,6 +214,17 @@ internal class FileCacheAccountSecretsManager(
|
|||||||
override fun invalidate() {
|
override fun invalidate() {
|
||||||
file.delete()
|
file.delete()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun saveSecretsToFile(file: File, account: BotAccount, secrets: AccountSecrets) {
|
||||||
|
file.writeBytes(
|
||||||
|
TEA.encrypt(
|
||||||
|
AccountSecretsImpl(secrets).toByteArray(AccountSecretsImpl.serializer()),
|
||||||
|
account.passwordMd5
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class CombinedAccountSecretsManager(
|
internal class CombinedAccountSecretsManager(
|
||||||
@ -218,7 +253,7 @@ internal fun BotConfiguration.createAccountsSecretsManager(logger: MiraiLogger):
|
|||||||
return CombinedAccountSecretsManager(
|
return CombinedAccountSecretsManager(
|
||||||
MemoryAccountSecretsManager(),
|
MemoryAccountSecretsManager(),
|
||||||
FileCacheAccountSecretsManager(
|
FileCacheAccountSecretsManager(
|
||||||
actualCacheDir().resolve("account.secrets"),
|
accountSecretsFile(),
|
||||||
logger
|
logger
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -20,3 +20,4 @@ internal fun BotConfiguration.contactCacheDir(): File = actualCacheDir().resolve
|
|||||||
internal fun BotConfiguration.friendCacheFile(): File = contactCacheDir().resolveCreateFile("friends.json")
|
internal fun BotConfiguration.friendCacheFile(): File = contactCacheDir().resolveCreateFile("friends.json")
|
||||||
internal fun BotConfiguration.groupCacheDir(): File = contactCacheDir().resolveMkdir("groups")
|
internal fun BotConfiguration.groupCacheDir(): File = contactCacheDir().resolveMkdir("groups")
|
||||||
internal fun BotConfiguration.groupCacheFile(groupId: Long): File = groupCacheDir().resolveCreateFile("$groupId.json")
|
internal fun BotConfiguration.groupCacheFile(groupId: Long): File = groupCacheDir().resolveCreateFile("$groupId.json")
|
||||||
|
internal fun BotConfiguration.accountSecretsFile(): File = actualCacheDir().resolve("account.secrets")
|
@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019-2021 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.internal.network.impl.netty
|
||||||
|
|
||||||
|
import net.mamoe.mirai.internal.network.components.AccountSecretsImpl
|
||||||
|
import net.mamoe.mirai.internal.network.components.AccountSecretsManager
|
||||||
|
import net.mamoe.mirai.internal.network.components.FileCacheAccountSecretsManager
|
||||||
|
import net.mamoe.mirai.internal.network.framework.AbstractNettyNHTest
|
||||||
|
import net.mamoe.mirai.internal.network.handler.NetworkHandler
|
||||||
|
import net.mamoe.mirai.internal.test.runBlockingUnit
|
||||||
|
import net.mamoe.mirai.internal.utils.accountSecretsFile
|
||||||
|
import net.mamoe.mirai.utils.DeviceInfo
|
||||||
|
import net.mamoe.mirai.utils.getRandomByteArray
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
internal class AccountSecretsTest : AbstractNettyNHTest() {
|
||||||
|
@Test
|
||||||
|
fun `can login with no secrets`() = runBlockingUnit {
|
||||||
|
val file = bot.configuration.accountSecretsFile()
|
||||||
|
file.delete()
|
||||||
|
bot.login()
|
||||||
|
bot.network.assertState(NetworkHandler.State.OK)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `can login with good secrets`() = runBlockingUnit {
|
||||||
|
val file = bot.configuration.accountSecretsFile()
|
||||||
|
val s = AccountSecretsImpl(DeviceInfo.random(), bot.account)
|
||||||
|
FileCacheAccountSecretsManager.saveSecretsToFile(file, bot.account, s)
|
||||||
|
bot.login()
|
||||||
|
bot.network.assertState(NetworkHandler.State.OK)
|
||||||
|
assertEquals(s, bot.components[AccountSecretsManager].getSecrets(bot.account))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `can login with bad secrets`() = runBlockingUnit {
|
||||||
|
val file = bot.configuration.accountSecretsFile()
|
||||||
|
file.writeBytes(getRandomByteArray(16))
|
||||||
|
bot.login()
|
||||||
|
bot.network.assertState(NetworkHandler.State.OK)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user