Skip to content

Commit

Permalink
Add refresh token auth
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexProgrammerDE committed Oct 12, 2024
1 parent 5b7ff53 commit 0bca8e3
Show file tree
Hide file tree
Showing 17 changed files with 109 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@
import com.soulfiremc.grpc.generated.AccountTypeCredentials;
import com.soulfiremc.grpc.generated.CredentialsAuthRequest;
import com.soulfiremc.grpc.generated.InstanceConfig;
import com.soulfiremc.server.settings.PropertyKey;
import com.soulfiremc.server.account.AuthType;
import com.soulfiremc.server.account.MinecraftAccount;
import com.soulfiremc.server.settings.lib.SettingsImpl;
import com.soulfiremc.server.proxy.SFProxy;
import com.soulfiremc.server.settings.PropertyKey;
import com.soulfiremc.server.settings.lib.SettingsImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

Expand Down
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[versions]
log4j = "2.24.1"
grpc = "1.68.0"
protobuf = "4.28.2"
protobuf = "3.25.5"
via-version = "5.0.4-SNAPSHOT"
via-backwards = "5.0.4-SNAPSHOT"
via-rewind = "4.0.3-SNAPSHOT"
Expand Down
2 changes: 2 additions & 0 deletions proto/src/main/proto/soulfire/common.proto
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ enum AccountTypeCredentials {
MICROSOFT_BEDROCK_CREDENTIALS = 1;
THE_ALTENING = 3;
OFFLINE = 4;
MICROSOFT_JAVA_REFRESH_TOKEN = 5;
}

enum AccountTypeDeviceCode {
Expand All @@ -40,6 +41,7 @@ message MinecraftAccountProto {
OFFLINE = 4;
MICROSOFT_JAVA_DEVICE_CODE = 5;
MICROSOFT_BEDROCK_DEVICE_CODE = 6;
MICROSOFT_JAVA_REFRESH_TOKEN = 7;
}

message OnlineSimpleJavaData {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import com.google.gson.JsonObject;
import com.soulfiremc.grpc.generated.InstanceListResponse;
import com.soulfiremc.server.account.MCAuthService;
import com.soulfiremc.server.account.MinecraftAccount;
import com.soulfiremc.server.account.OfflineAuthService;
import com.soulfiremc.server.api.AttackLifecycle;
import com.soulfiremc.server.api.EventBusOwner;
Expand All @@ -34,13 +35,12 @@
import com.soulfiremc.server.protocol.BotConnectionFactory;
import com.soulfiremc.server.protocol.netty.ResolveUtil;
import com.soulfiremc.server.protocol.netty.SFNettyHelper;
import com.soulfiremc.server.proxy.SFProxy;
import com.soulfiremc.server.settings.AccountSettings;
import com.soulfiremc.server.settings.BotSettings;
import com.soulfiremc.server.settings.ProxySettings;
import com.soulfiremc.server.account.MinecraftAccount;
import com.soulfiremc.server.settings.lib.SettingsDelegate;
import com.soulfiremc.server.settings.lib.SettingsImpl;
import com.soulfiremc.server.proxy.SFProxy;
import com.soulfiremc.server.util.MathHelper;
import com.soulfiremc.server.util.TimeUtil;
import com.soulfiremc.server.viaversion.SFVersionConstants;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public enum AuthType {
MICROSOFT_BEDROCK_CREDENTIALS("Microsoft Bedrock Credentials", BedrockData.class),
MICROSOFT_JAVA_DEVICE_CODE("Microsoft Java Device Code", OnlineChainJavaData.class),
MICROSOFT_BEDROCK_DEVICE_CODE("Microsoft Bedrock Device Code", BedrockData.class),
MICROSOFT_JAVA_REFRESH_TOKEN("Microsoft Java Refresh Token", OnlineChainJavaData.class),
THE_ALTENING("The Altening", OnlineSimpleJavaData.class),
OFFLINE("Offline", OfflineJavaData.class);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,14 @@
import java.util.function.Consumer;

public sealed interface MCAuthService<I, T>
permits MSBedrockCredentialsAuthService, MSBedrockDeviceCodeAuthService, MSJavaCredentialsAuthService, MSJavaDeviceCodeAuthService, OfflineAuthService, TheAlteningAuthService {
permits MSBedrockCredentialsAuthService, MSBedrockDeviceCodeAuthService, MSJavaCredentialsAuthService, MSJavaDeviceCodeAuthService, MSJavaRefreshTokenAuthService, OfflineAuthService, TheAlteningAuthService {
static MCAuthService<String, ?> convertService(AccountTypeCredentials service) {
return switch (service) {
case MICROSOFT_JAVA_CREDENTIALS -> MSJavaCredentialsAuthService.INSTANCE;
case MICROSOFT_BEDROCK_CREDENTIALS -> MSBedrockCredentialsAuthService.INSTANCE;
case THE_ALTENING -> TheAlteningAuthService.INSTANCE;
case OFFLINE -> OfflineAuthService.INSTANCE;
case MICROSOFT_JAVA_REFRESH_TOKEN -> MSJavaRefreshTokenAuthService.INSTANCE;
case UNRECOGNIZED -> throw new IllegalArgumentException("Unrecognized service");
};
}
Expand All @@ -54,6 +55,7 @@ public sealed interface MCAuthService<I, T>
case OFFLINE -> OfflineAuthService.INSTANCE;
case MICROSOFT_JAVA_DEVICE_CODE -> MSJavaDeviceCodeAuthService.INSTANCE;
case MICROSOFT_BEDROCK_DEVICE_CODE -> MSBedrockDeviceCodeAuthService.INSTANCE;
case MICROSOFT_JAVA_REFRESH_TOKEN -> MSJavaRefreshTokenAuthService.INSTANCE;
case UNRECOGNIZED -> throw new IllegalArgumentException("Unrecognized service");
};
}
Expand All @@ -66,6 +68,7 @@ public sealed interface MCAuthService<I, T>
case MICROSOFT_BEDROCK_DEVICE_CODE -> MSBedrockDeviceCodeAuthService.INSTANCE;
case THE_ALTENING -> TheAlteningAuthService.INSTANCE;
case OFFLINE -> OfflineAuthService.INSTANCE;
case MICROSOFT_JAVA_REFRESH_TOKEN -> MSJavaRefreshTokenAuthService.INSTANCE;
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ public MSBedrockCredentialsAuthData createData(String data) {
throw new IllegalArgumentException("Invalid data!");
}

var email = split[0].trim();
var password = split[1].trim();
var email = split[0].strip();
var password = split[1].strip();
if (!EmailValidator.getInstance().isValid(email)) {
throw new IllegalArgumentException("Invalid email!");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ public MSJavaCredentialsAuthData createData(String data) {
throw new IllegalArgumentException("Invalid data!");
}

var email = split[0].trim();
var password = split[1].trim();
var email = split[0].strip();
var password = split[1].strip();
if (!EmailValidator.getInstance().isValid(email)) {
throw new IllegalArgumentException("Invalid email!");
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* SoulFire
* Copyright (C) 2024 AlexProgrammerDE
*
* 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 com.soulfiremc.server.account;

import com.soulfiremc.server.account.service.OnlineChainJavaData;
import com.soulfiremc.server.proxy.SFProxy;
import com.soulfiremc.server.util.LenniHttpHelper;
import net.raphimc.minecraftauth.MinecraftAuth;
import net.raphimc.minecraftauth.step.msa.StepMsaToken;

import java.util.concurrent.CompletableFuture;

public final class MSJavaRefreshTokenAuthService
implements MCAuthService<String, MSJavaRefreshTokenAuthService.MSJavaRefreshTokenAuthData> {
public static final MSJavaRefreshTokenAuthService INSTANCE = new MSJavaRefreshTokenAuthService();

private MSJavaRefreshTokenAuthService() {}

@Override
public CompletableFuture<MinecraftAccount> login(MSJavaRefreshTokenAuthData data, SFProxy proxyData) {
return CompletableFuture.supplyAsync(() -> {
var flow = MinecraftAuth.JAVA_CREDENTIALS_LOGIN;
try {
return AuthHelpers.fromFullJavaSession(AuthType.MICROSOFT_JAVA_REFRESH_TOKEN, flow, flow.getFromInput(
LenniHttpHelper.createLenniMCAuthHttpClient(proxyData),
new StepMsaToken.RefreshToken(data.refreshToken)));
} catch (Exception e) {
throw new RuntimeException(e);
}
});
}

@Override
public MSJavaRefreshTokenAuthData createData(String data) {
return new MSJavaRefreshTokenAuthData(data.strip());
}

@Override
public CompletableFuture<MinecraftAccount> refresh(MinecraftAccount account, SFProxy proxyData) {
return CompletableFuture.supplyAsync(() -> {
var flow = MinecraftAuth.JAVA_CREDENTIALS_LOGIN;
var fullJavaSession = flow.fromJson(((OnlineChainJavaData) account.accountData()).authChain());
try {
return AuthHelpers.fromFullJavaSession(AuthType.MICROSOFT_JAVA_REFRESH_TOKEN, flow, flow.refresh(
LenniHttpHelper.createLenniMCAuthHttpClient(proxyData),
fullJavaSession));
} catch (Exception e) {
throw new RuntimeException(e);
}
});
}

@Override
public boolean isExpired(MinecraftAccount account) {
var flow = MinecraftAuth.JAVA_CREDENTIALS_LOGIN;
return flow.fromJson(((OnlineChainJavaData) account.accountData()).authChain()).isExpired();
}

@Override
public boolean isExpiredOrOutdated(MinecraftAccount account) {
var flow = MinecraftAuth.JAVA_CREDENTIALS_LOGIN;
return flow.fromJson(((OnlineChainJavaData) account.accountData()).authChain()).isExpiredOrOutdated();
}

public record MSJavaRefreshTokenAuthData(String refreshToken) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(
} else {
Jws<Claims> claims = null;
// remove authorization type prefix
var token = value.substring(RPCConstants.BEARER_TYPE.length()).trim();
var token = value.substring(RPCConstants.BEARER_TYPE.length()).strip();
try {
// verify token signature and parse claims
claims = parser.parseSignedClaims(token);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

import com.soulfiremc.server.InstanceManager;
import com.soulfiremc.server.SoulFireScheduler;
import com.soulfiremc.server.account.MinecraftAccount;
import com.soulfiremc.server.account.service.OnlineJavaDataLike;
import com.soulfiremc.server.api.EventBusOwner;
import com.soulfiremc.server.api.event.EventExceptionHandler;
import com.soulfiremc.server.api.event.SoulFireBotEvent;
Expand All @@ -30,10 +32,8 @@
import com.soulfiremc.server.protocol.bot.state.TickHookContext;
import com.soulfiremc.server.protocol.netty.ResolveUtil;
import com.soulfiremc.server.protocol.netty.ViaClientSession;
import com.soulfiremc.server.account.MinecraftAccount;
import com.soulfiremc.server.account.service.OnlineJavaDataLike;
import com.soulfiremc.server.settings.lib.SettingsSource;
import com.soulfiremc.server.proxy.SFProxy;
import com.soulfiremc.server.settings.lib.SettingsSource;
import com.soulfiremc.server.util.TimeUtil;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import io.netty.channel.EventLoopGroup;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@
package com.soulfiremc.server.protocol;

import com.soulfiremc.server.InstanceManager;
import com.soulfiremc.server.account.MinecraftAccount;
import com.soulfiremc.server.api.event.attack.BotConnectionInitEvent;
import com.soulfiremc.server.protocol.netty.ResolveUtil;
import com.soulfiremc.server.proxy.SFProxy;
import com.soulfiremc.server.settings.BotSettings;
import com.soulfiremc.server.account.MinecraftAccount;
import com.soulfiremc.server.settings.lib.SettingsSource;
import com.soulfiremc.server.proxy.SFProxy;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import io.netty.channel.EventLoopGroup;
import org.geysermc.mcprotocollib.network.BuiltinFlags;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public class SFSessionService {
public SFSessionService(AuthType authType, SFProxy proxyData) {
this.joinEndpoint =
switch (authType) {
case MICROSOFT_JAVA_CREDENTIALS, MICROSOFT_JAVA_DEVICE_CODE -> MOJANG_JOIN_URI;
case MICROSOFT_JAVA_CREDENTIALS, MICROSOFT_JAVA_DEVICE_CODE, MICROSOFT_JAVA_REFRESH_TOKEN -> MOJANG_JOIN_URI;
case THE_ALTENING -> THE_ALTENING_JOIN_URI;
case OFFLINE, MICROSOFT_BEDROCK_CREDENTIALS, MICROSOFT_BEDROCK_DEVICE_CODE -> throw new IllegalArgumentException("Invalid auth type");
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
*/
package com.soulfiremc.server.protocol.netty;

import com.soulfiremc.server.account.service.BedrockData;
import com.soulfiremc.server.protocol.BotConnection;
import com.soulfiremc.server.protocol.SFProtocolConstants;
import com.soulfiremc.server.account.service.BedrockData;
import com.soulfiremc.server.proxy.SFProxy;
import com.soulfiremc.server.viaversion.SFVLPipeline;
import com.soulfiremc.server.viaversion.SFVersionConstants;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@
package com.soulfiremc.server.settings.lib;

import com.google.gson.JsonElement;
import com.soulfiremc.server.settings.PropertyKey;
import com.soulfiremc.server.account.MinecraftAccount;
import com.soulfiremc.server.proxy.SFProxy;
import com.soulfiremc.server.settings.PropertyKey;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@
import com.soulfiremc.grpc.generated.InstanceConfig;
import com.soulfiremc.grpc.generated.SettingsEntry;
import com.soulfiremc.grpc.generated.SettingsNamespace;
import com.soulfiremc.server.settings.PropertyKey;
import com.soulfiremc.server.account.AuthType;
import com.soulfiremc.server.account.MinecraftAccount;
import com.soulfiremc.server.account.service.AccountData;
import com.soulfiremc.server.proxy.SFProxy;
import com.soulfiremc.server.settings.PropertyKey;
import com.soulfiremc.server.util.SocketAddressHelper;
import com.soulfiremc.server.util.structs.GsonInstance;
import lombok.SneakyThrows;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@
package com.soulfiremc.server.settings.lib;

import com.google.gson.JsonElement;
import com.soulfiremc.server.settings.PropertyKey;
import com.soulfiremc.server.account.MinecraftAccount;
import com.soulfiremc.server.settings.property.*;
import com.soulfiremc.server.proxy.SFProxy;
import com.soulfiremc.server.settings.PropertyKey;
import com.soulfiremc.server.settings.property.*;
import com.soulfiremc.server.util.SFHelpers;
import com.soulfiremc.server.util.structs.GsonInstance;

Expand Down

0 comments on commit 0bca8e3

Please sign in to comment.