Fix yggdrasil login.

This commit is contained in:
huangyuhui
2017-08-19 23:44:12 +08:00
parent 383453f9af
commit 432fd287c9
6 changed files with 37 additions and 24 deletions

View File

@@ -66,7 +66,14 @@ object Settings {
continue@loop continue@loop
} }
val account = factory.fromStorage(settings) val account: Account
try {
account = factory.fromStorage(settings)
} catch (e: Exception) {
SETTINGS.accounts.remove(name)
// storage is malformed, delete.
continue@loop
}
if (account.username != name) { if (account.username != name) {
SETTINGS.accounts.remove(name) SETTINGS.accounts.remove(name)

View File

@@ -30,6 +30,7 @@ import javafx.scene.control.Label
import javafx.scene.control.ToggleGroup import javafx.scene.control.ToggleGroup
import org.jackhuang.hmcl.auth.Account import org.jackhuang.hmcl.auth.Account
import org.jackhuang.hmcl.auth.OfflineAccount import org.jackhuang.hmcl.auth.OfflineAccount
import org.jackhuang.hmcl.auth.yggdrasil.InvalidCredentialsException
import org.jackhuang.hmcl.auth.yggdrasil.YggdrasilAccount import org.jackhuang.hmcl.auth.yggdrasil.YggdrasilAccount
import org.jackhuang.hmcl.i18n import org.jackhuang.hmcl.i18n
import org.jackhuang.hmcl.setting.Settings import org.jackhuang.hmcl.setting.Settings
@@ -80,6 +81,9 @@ class AccountsPage() : StackPane(), DecoratorPage {
} }
cboType.selectionModel.select(0) cboType.selectionModel.select(0)
txtPassword.setOnAction { onCreationAccept() }
txtUsername.setOnAction { onCreationAccept() }
Settings.selectedAccountProperty.addListener(listener) Settings.selectedAccountProperty.addListener(listener)
loadAccounts() loadAccounts()
@@ -150,6 +154,8 @@ class AccountsPage() : StackPane(), DecoratorPage {
Settings.addAccount(account) Settings.addAccount(account)
dialog.close() dialog.close()
loadAccounts() loadAccounts()
} else if (account is InvalidCredentialsException) {
lblCreationWarning.text = i18n("login.wrong_password")
} else if (account is Exception) { } else if (account is Exception) {
lblCreationWarning.text = account.localizedMessage lblCreationWarning.text = account.localizedMessage
} }

View File

@@ -42,10 +42,7 @@ object DialogController {
pane.dialog = Controllers.dialog(pane) pane.dialog = Controllers.dialog(pane)
} }
latch.await() latch.await()
if (res.get() == null) return res.get() ?: throw SilentException()
throw SilentException()
else
return res.get()
} }
return null return null
} }

View File

@@ -20,6 +20,6 @@ package org.jackhuang.hmcl.auth.yggdrasil
data class RefreshRequest( data class RefreshRequest(
val clientToken: String, val clientToken: String,
val accessToken: String, val accessToken: String,
val selectedProfile: GameProfile?, val selectedProfile: GameProfile? = null,
val requestUser: Boolean = true val requestUser: Boolean = true
) )

View File

@@ -17,8 +17,7 @@
*/ */
package org.jackhuang.hmcl.auth.yggdrasil package org.jackhuang.hmcl.auth.yggdrasil
data class ValidateRequest ( data class ValidateRequest @JvmOverloads constructor(
val clientToken: String = "", val clientToken: String = "",
val accessToken: String = "" val accessToken: String = ""
) { )
}

View File

@@ -33,7 +33,7 @@ class YggdrasilAccount private constructor(override val username: String): Accou
private var password: String? = null private var password: String? = null
private var userId: String? = null private var userId: String? = null
private var accessToken: String? = null private var accessToken: String? = null
private var clientToken: String = UUID.randomUUID().toString() private var clientToken: String = randomToken()
private var isOnline: Boolean = false private var isOnline: Boolean = false
private var userProperties = PropertyMap() private var userProperties = PropertyMap()
var selectedProfile: GameProfile? = null var selectedProfile: GameProfile? = null
@@ -96,7 +96,7 @@ class YggdrasilAccount private constructor(override val username: String): Accou
isOnline = true isOnline = true
return return
} }
logIn1(ROUTE_REFRESH, RefreshRequest(accessToken!!, clientToken, selectedProfile), proxy) logIn1(ROUTE_REFRESH, RefreshRequest(clientToken = clientToken, accessToken = accessToken!!, selectedProfile = selectedProfile), proxy)
} else if (isNotBlank(password)) { } else if (isNotBlank(password)) {
logIn1(ROUTE_AUTHENTICATE, AuthenticationRequest(username, password!!, clientToken), proxy) logIn1(ROUTE_AUTHENTICATE, AuthenticationRequest(username, password!!, clientToken), proxy)
} else } else
@@ -122,7 +122,7 @@ class YggdrasilAccount private constructor(override val username: String): Accou
userProperties.clear() userProperties.clear()
accessToken = response.accessToken accessToken = response.accessToken
if (user != null && user.properties != null) if (user?.properties != null)
userProperties.putAll(user.properties) userProperties.putAll(user.properties)
} }
@@ -140,18 +140,19 @@ class YggdrasilAccount private constructor(override val username: String): Accou
val result = HashMap<Any, Any>() val result = HashMap<Any, Any>()
result[STORAGE_KEY_USER_NAME] = username result[STORAGE_KEY_USER_NAME] = username
result[STORAGE_KEY_CLIENT_TOKEN] = clientToken
if (userId != null) if (userId != null)
result[STORAGE_KEY_USER_ID] = userId!! result[STORAGE_KEY_USER_ID] = userId!!
if (!userProperties.isEmpty()) if (!userProperties.isEmpty())
result[STORAGE_KEY_USER_PROPERTIES] = userProperties.toList() result[STORAGE_KEY_USER_PROPERTIES] = userProperties.toList()
val profile = selectedProfile val profile = selectedProfile
if (profile != null && profile.name != null && profile.id != null) { if (profile?.name != null && profile.id != null) {
result[STORAGE_KEY_PROFILE_NAME] = profile.name result[STORAGE_KEY_PROFILE_NAME] = profile.name
result[STORAGE_KEY_PROFILE_ID] = profile.id result[STORAGE_KEY_PROFILE_ID] = UUIDTypeAdapter.fromUUID(profile.id)
if (!profile.properties.isEmpty()) if (!profile.properties.isEmpty())
result[STORAGE_KEY_PROFILE_PROPERTIES] = profile.properties.toList() result[STORAGE_KEY_PROFILE_PROPERTIES] = profile.properties.toList()
} }
if (accessToken?.isNotBlank() ?: false) if (accessToken != null && accessToken!!.isNotBlank())
result[STORAGE_KEY_ACCESS_TOKEN] = accessToken!! result[STORAGE_KEY_ACCESS_TOKEN] = accessToken!!
return result return result
@@ -167,11 +168,12 @@ class YggdrasilAccount private constructor(override val username: String): Accou
if (response.error?.isNotBlank() ?: false) { if (response.error?.isNotBlank() ?: false) {
LOG.severe("Failed to log in, the auth server returned an error: " + response.error + ", message: " + response.errorMessage + ", cause: " + response.cause) LOG.severe("Failed to log in, the auth server returned an error: " + response.error + ", message: " + response.errorMessage + ", cause: " + response.cause)
throw when (response.errorMessage) { if (response.errorMessage != null)
"Invalid token." -> InvalidTokenException(this) if (response.errorMessage.contains("Invalid credentials"))
"Invalid credentials. Invalid username or password." -> InvalidCredentialsException(this) throw InvalidCredentialsException(this)
else -> AuthenticationException("Request error: ${response.errorMessage}") else if (response.errorMessage.contains("Invalid token"))
} throw InvalidTokenException(this)
throw AuthenticationException("Request error: ${response.errorMessage}")
} }
return response return response
@@ -183,10 +185,8 @@ class YggdrasilAccount private constructor(override val username: String): Accou
} }
private fun checkTokenValidity(proxy: Proxy): Boolean { private fun checkTokenValidity(proxy: Proxy): Boolean {
val access = accessToken val access = accessToken ?: return false
try { try {
if (access == null)
return false
makeRequest(ROUTE_VALIDATE, ValidateRequest(clientToken, access), proxy) makeRequest(ROUTE_VALIDATE, ValidateRequest(clientToken, access), proxy)
return true return true
} catch (e: AuthenticationException) { } catch (e: AuthenticationException) {
@@ -215,6 +215,9 @@ class YggdrasilAccount private constructor(override val username: String): Accou
private val STORAGE_KEY_USER_NAME = "username" private val STORAGE_KEY_USER_NAME = "username"
private val STORAGE_KEY_USER_ID = "userid" private val STORAGE_KEY_USER_ID = "userid"
private val STORAGE_KEY_USER_PROPERTIES = "userProperties" private val STORAGE_KEY_USER_PROPERTIES = "userProperties"
private val STORAGE_KEY_CLIENT_TOKEN = "clientToken"
fun randomToken() = UUIDTypeAdapter.fromUUID(UUID.randomUUID())
override fun fromUsername(username: String, password: String): YggdrasilAccount { override fun fromUsername(username: String, password: String): YggdrasilAccount {
val account = YggdrasilAccount(username) val account = YggdrasilAccount(username)
@@ -223,10 +226,11 @@ class YggdrasilAccount private constructor(override val username: String): Accou
} }
override fun fromStorage(storage: Map<Any, Any>): YggdrasilAccount { override fun fromStorage(storage: Map<Any, Any>): YggdrasilAccount {
val username = storage[STORAGE_KEY_USER_NAME] as? String ?: throw IllegalArgumentException("storage does not have key $STORAGE_KEY_USER_NAME") val username = storage[STORAGE_KEY_USER_NAME] as? String? ?: throw IllegalArgumentException("storage does not have key $STORAGE_KEY_USER_NAME")
val account = YggdrasilAccount(username) val account = YggdrasilAccount(username)
account.userId = storage[STORAGE_KEY_USER_ID] as? String ?: username account.userId = storage[STORAGE_KEY_USER_ID] as? String ?: username
account.accessToken = storage[STORAGE_KEY_ACCESS_TOKEN] as? String account.accessToken = storage[STORAGE_KEY_ACCESS_TOKEN] as? String
account.clientToken = storage[STORAGE_KEY_CLIENT_TOKEN] as? String? ?: throw IllegalArgumentException("storage does not have key $STORAGE_KEY_CLIENT_TOKEN")
val userProperties = storage[STORAGE_KEY_USER_PROPERTIES] as? List<*> val userProperties = storage[STORAGE_KEY_USER_PROPERTIES] as? List<*>
if (userProperties != null) if (userProperties != null)
account.userProperties.fromList(userProperties) account.userProperties.fromList(userProperties)