feat(account): OAuth account relogin.

This commit is contained in:
huanghongxun
2021-10-12 22:00:41 +08:00
parent 948d64237e
commit 23c2c0689c
13 changed files with 209 additions and 43 deletions

View File

@@ -1,6 +1,6 @@
/*
* Hello Minecraft! Launcher
* Copyright (C) 2020 huangyuhui <huanghongxun2008@126.com> and contributors
* Copyright (C) 2021 huangyuhui <huanghongxun2008@126.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -60,11 +60,6 @@ public abstract class Account implements Observable {
*/
public abstract AuthInfo logIn() throws AuthenticationException;
/**
* Login with specified password.
*/
public abstract AuthInfo logInWithPassword(String password) throws AuthenticationException;
/**
* Play offline.
* @return the specific offline player's info.

View File

@@ -0,0 +1,29 @@
/*
* Hello Minecraft! Launcher
* Copyright (C) 2021 huangyuhui <huanghongxun2008@126.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.jackhuang.hmcl.auth;
public abstract class ClassicAccount extends Account {
/**
* Login with specified password.
*
* When credentials expired, the auth server will ask you to login with password to refresh
* credentials.
*/
public abstract AuthInfo logInWithPassword(String password) throws AuthenticationException;
}

View File

@@ -0,0 +1,56 @@
/*
* Hello Minecraft! Launcher
* Copyright (C) 2021 huangyuhui <huanghongxun2008@126.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.jackhuang.hmcl.auth;
import java.util.UUID;
public abstract class OAuthAccount extends Account {
/**
* Fully login.
*
* OAuth server may ask us to do fully login because too frequent action to log in, IP changed,
* or some other vulnerabilities detected.
*
* Difference between logIn & logInWhenCredentialsExpired.
* logIn only update access token by refresh token, and will not ask user to login by opening the authorization
* page in web browser.
* logInWhenCredentialsExpired will open the authorization page in web browser, asking user to select an account
* (and enter password or PIN if necessary).
*/
public abstract AuthInfo logInWhenCredentialsExpired() throws AuthenticationException;
public static class WrongAccountException extends AuthenticationException {
private final UUID expected;
private final UUID actual;
public WrongAccountException(UUID expected, UUID actual) {
super("Expected account " + expected + ", but found " + actual);
this.expected = expected;
this.actual = actual;
}
public UUID getExpected() {
return expected;
}
public UUID getActual() {
return actual;
}
}
}

View File

@@ -33,7 +33,7 @@ import java.util.logging.Level;
import static java.util.Objects.requireNonNull;
import static org.jackhuang.hmcl.util.Logging.LOG;
public class MicrosoftAccount extends Account {
public class MicrosoftAccount extends OAuthAccount {
protected final MicrosoftService service;
protected UUID characterUUID;
@@ -99,8 +99,11 @@ public class MicrosoftAccount extends Account {
}
@Override
public AuthInfo logInWithPassword(String password) throws AuthenticationException {
public AuthInfo logInWhenCredentialsExpired() throws AuthenticationException {
MicrosoftSession acquiredSession = service.authenticate();
if (!Objects.equals(characterUUID, acquiredSession.getProfile().getId())) {
throw new WrongAccountException(characterUUID, acquiredSession.getProfile().getId());
}
if (acquiredSession.getProfile() == null) {
session = service.refresh(acquiredSession);

View File

@@ -134,11 +134,6 @@ public class OfflineAccount extends Account {
}
}
@Override
public AuthInfo logInWithPassword(String password) throws AuthenticationException {
return logIn();
}
@Override
public Optional<AuthInfo> playOffline() throws AuthenticationException {
return Optional.of(logIn());

View File

@@ -18,14 +18,7 @@
package org.jackhuang.hmcl.auth.yggdrasil;
import javafx.beans.binding.ObjectBinding;
import org.jackhuang.hmcl.auth.Account;
import org.jackhuang.hmcl.auth.AuthInfo;
import org.jackhuang.hmcl.auth.AuthenticationException;
import org.jackhuang.hmcl.auth.CharacterDeletedException;
import org.jackhuang.hmcl.auth.CharacterSelector;
import org.jackhuang.hmcl.auth.CredentialExpiredException;
import org.jackhuang.hmcl.auth.NoCharacterException;
import org.jackhuang.hmcl.auth.ServerResponseMalformedException;
import org.jackhuang.hmcl.auth.*;
import org.jackhuang.hmcl.util.gson.UUIDTypeAdapter;
import org.jackhuang.hmcl.util.javafx.BindingMapping;
@@ -36,7 +29,7 @@ import java.util.logging.Level;
import static java.util.Objects.requireNonNull;
import static org.jackhuang.hmcl.util.Logging.LOG;
public class YggdrasilAccount extends Account {
public class YggdrasilAccount extends ClassicAccount {
protected final YggdrasilService service;
protected final UUID characterUUID;