mirror of
https://github.com/GravitLauncher/Launcher
synced 2025-02-23 03:59:44 +03:00
Merge branch 'release/5.2.3'
This commit is contained in:
commit
b48059998f
109 changed files with 807 additions and 3303 deletions
29
.github/workflows/push.yml
vendored
29
.github/workflows/push.yml
vendored
|
@ -16,10 +16,10 @@ jobs:
|
||||||
path: ~/.gradle/caches
|
path: ~/.gradle/caches
|
||||||
key: gravit-${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }}-launcher
|
key: gravit-${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }}-launcher
|
||||||
|
|
||||||
- name: Set up JDK 11
|
- name: Set up JDK 17
|
||||||
uses: actions/setup-java@v1
|
uses: actions/setup-java@v1
|
||||||
with:
|
with:
|
||||||
java-version: 11
|
java-version: 17
|
||||||
|
|
||||||
- name: Grant execute permission for gradlew
|
- name: Grant execute permission for gradlew
|
||||||
run: chmod +x gradlew
|
run: chmod +x gradlew
|
||||||
|
@ -30,16 +30,13 @@ jobs:
|
||||||
- name: Create artifacts
|
- name: Create artifacts
|
||||||
run: |
|
run: |
|
||||||
mkdir -p artifacts/modules
|
mkdir -p artifacts/modules
|
||||||
cd LaunchServer/build/libs/
|
cd LaunchServer/build/libs
|
||||||
zip -r -9 ../../../artifacts/libraries.zip * -x "LaunchServer.jar" -x "LaunchServer-clean.jar"
|
zip -r -9 ../../../artifacts/libraries.zip * -x "LaunchServer.jar" -x "LaunchServer-clean.jar"
|
||||||
cp LaunchServer.jar ../../../artifacts/LaunchServer.jar
|
cp LaunchServer.jar ../../../artifacts/LaunchServer.jar
|
||||||
cd ../../../ServerWrapper/build/libs
|
cd ../../..
|
||||||
cp ServerWrapper.jar ../../../artifacts/ServerWrapper.jar
|
cp ServerWrapper/build/libs/ServerWrapper.jar artifacts/ServerWrapper.jar
|
||||||
cd ../../../LauncherAuthlib/build/libs
|
cp LauncherAuthlib/build/libs/LauncherAuthlib.jar artifacts/LauncherAuthlib.jar
|
||||||
cp LauncherAuthlib.jar ../../../artifacts/LauncherAuthlib.jar
|
|
||||||
cd ../../../
|
|
||||||
cp modules/*_module/build/libs/*.jar artifacts/modules || true
|
cp modules/*_module/build/libs/*.jar artifacts/modules || true
|
||||||
cp modules/*_swmodule/build/libs/*.jar artifacts/modules || true
|
|
||||||
cp modules/*_lmodule/build/libs/*.jar artifacts/modules || true
|
cp modules/*_lmodule/build/libs/*.jar artifacts/modules || true
|
||||||
|
|
||||||
- name: Upload artifacts
|
- name: Upload artifacts
|
||||||
|
@ -56,10 +53,11 @@ jobs:
|
||||||
if: startsWith(github.event.ref, 'refs/tags')
|
if: startsWith(github.event.ref, 'refs/tags')
|
||||||
run: |
|
run: |
|
||||||
cd artifacts
|
cd artifacts
|
||||||
zip -9 LauncherBase.zip libraries.zip LaunchServer.jar
|
zip -r -9 Release.zip *
|
||||||
zip -j -9 LaunchServerModules.zip ../modules/*_module/build/libs/*.jar
|
zip -j -9 LaunchServerModules.zip ../modules/*_module/build/libs/*.jar
|
||||||
zip -j -9 LauncherModules.zip ../modules/*_lmodule/build/libs/*.jar
|
zip -j -9 LauncherModules.zip ../modules/*_lmodule/build/libs/*.jar
|
||||||
zip -j -9 ServerWrapperModules.zip ../modules/*_swmodule/build/libs/*.jar
|
cd ../LaunchServer/build/libs
|
||||||
|
zip -r -9 ../../../artifacts/LauncherBase.zip * -x "LaunchServer-clean.jar"
|
||||||
|
|
||||||
- name: Create release
|
- name: Create release
|
||||||
id: create_release
|
id: create_release
|
||||||
|
@ -74,11 +72,4 @@ jobs:
|
||||||
draft: false
|
draft: false
|
||||||
prerelease: false
|
prerelease: false
|
||||||
files: |
|
files: |
|
||||||
libraries.zip
|
artifacts/*
|
||||||
LaunchServer.jar
|
|
||||||
ServerWrapper.jar
|
|
||||||
LauncherAuthlib.jar
|
|
||||||
LauncherModules.zip
|
|
||||||
LaunchServerModules.zip
|
|
||||||
ServerWrapperModules.zip
|
|
||||||
LauncherBase.zip
|
|
||||||
|
|
|
@ -12,8 +12,8 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceCompatibility = '11'
|
sourceCompatibility = '17'
|
||||||
targetCompatibility = '11'
|
targetCompatibility = '17'
|
||||||
|
|
||||||
configurations {
|
configurations {
|
||||||
compileOnlyA
|
compileOnlyA
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import pro.gravit.launcher.Launcher;
|
import pro.gravit.launcher.Launcher;
|
||||||
import pro.gravit.launcher.NeedGarbageCollection;
|
import pro.gravit.launcher.NeedGarbageCollection;
|
||||||
import pro.gravit.launcher.hasher.HashedDir;
|
|
||||||
import pro.gravit.launcher.managers.ConfigManager;
|
import pro.gravit.launcher.managers.ConfigManager;
|
||||||
import pro.gravit.launcher.managers.GarbageManager;
|
import pro.gravit.launcher.managers.GarbageManager;
|
||||||
import pro.gravit.launcher.modules.events.ClosePhase;
|
import pro.gravit.launcher.modules.events.ClosePhase;
|
||||||
|
@ -40,10 +39,7 @@
|
||||||
import java.lang.invoke.MethodType;
|
import java.lang.invoke.MethodType;
|
||||||
import java.nio.file.*;
|
import java.nio.file.*;
|
||||||
import java.nio.file.attribute.BasicFileAttributes;
|
import java.nio.file.attribute.BasicFileAttributes;
|
||||||
import java.security.interfaces.ECPrivateKey;
|
|
||||||
import java.security.interfaces.ECPublicKey;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
@ -89,10 +85,6 @@ public final class LaunchServer implements Runnable, AutoCloseable, Reconfigurab
|
||||||
* This object contains runtime configuration
|
* This object contains runtime configuration
|
||||||
*/
|
*/
|
||||||
public final LaunchServerRuntimeConfig runtime;
|
public final LaunchServerRuntimeConfig runtime;
|
||||||
@Deprecated
|
|
||||||
public final ECPublicKey publicKey;
|
|
||||||
@Deprecated
|
|
||||||
public final ECPrivateKey privateKey;
|
|
||||||
/**
|
/**
|
||||||
* Pipeline for building JAR
|
* Pipeline for building JAR
|
||||||
*/
|
*/
|
||||||
|
@ -121,18 +113,15 @@ public final class LaunchServer implements Runnable, AutoCloseable, Reconfigurab
|
||||||
// Server
|
// Server
|
||||||
public final CommandHandler commandHandler;
|
public final CommandHandler commandHandler;
|
||||||
public final NettyServerSocketHandler nettyServerSocketHandler;
|
public final NettyServerSocketHandler nettyServerSocketHandler;
|
||||||
@Deprecated
|
|
||||||
public final Timer taskPool;
|
|
||||||
public final ScheduledExecutorService service;
|
public final ScheduledExecutorService service;
|
||||||
public final AtomicBoolean started = new AtomicBoolean(false);
|
public final AtomicBoolean started = new AtomicBoolean(false);
|
||||||
public final LauncherModuleLoader launcherModuleLoader;
|
public final LauncherModuleLoader launcherModuleLoader;
|
||||||
private final Logger logger = LogManager.getLogger();
|
private final Logger logger = LogManager.getLogger();
|
||||||
public LaunchServerConfig config;
|
public LaunchServerConfig config;
|
||||||
@Deprecated
|
|
||||||
public volatile Map<String, HashedDir> updatesDirMap;
|
|
||||||
// Updates and profiles
|
// Updates and profiles
|
||||||
private volatile Set<ClientProfile> profilesList;
|
private volatile Set<ClientProfile> profilesList;
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
public LaunchServer(LaunchServerDirectories directories, LaunchServerEnv env, LaunchServerConfig config, LaunchServerRuntimeConfig runtimeConfig, LaunchServerConfigManager launchServerConfigManager, LaunchServerModulesManager modulesManager, KeyAgreementManager keyAgreementManager, CommandHandler commandHandler, CertificateManager certificateManager) throws IOException {
|
public LaunchServer(LaunchServerDirectories directories, LaunchServerEnv env, LaunchServerConfig config, LaunchServerRuntimeConfig runtimeConfig, LaunchServerConfigManager launchServerConfigManager, LaunchServerModulesManager modulesManager, KeyAgreementManager keyAgreementManager, CommandHandler commandHandler, CertificateManager certificateManager) throws IOException {
|
||||||
this.dir = directories.dir;
|
this.dir = directories.dir;
|
||||||
this.tmpDir = directories.tmpDir;
|
this.tmpDir = directories.tmpDir;
|
||||||
|
@ -143,13 +132,10 @@ public LaunchServer(LaunchServerDirectories directories, LaunchServerEnv env, La
|
||||||
this.profilesDir = directories.profilesDir;
|
this.profilesDir = directories.profilesDir;
|
||||||
this.updatesDir = directories.updatesDir;
|
this.updatesDir = directories.updatesDir;
|
||||||
this.keyAgreementManager = keyAgreementManager;
|
this.keyAgreementManager = keyAgreementManager;
|
||||||
this.publicKey = keyAgreementManager.ecdsaPublicKey;
|
|
||||||
this.privateKey = keyAgreementManager.ecdsaPrivateKey;
|
|
||||||
this.commandHandler = commandHandler;
|
this.commandHandler = commandHandler;
|
||||||
this.runtime = runtimeConfig;
|
this.runtime = runtimeConfig;
|
||||||
this.certificateManager = certificateManager;
|
this.certificateManager = certificateManager;
|
||||||
this.service = Executors.newScheduledThreadPool(config.netty.performance.schedulerThread);
|
this.service = Executors.newScheduledThreadPool(config.netty.performance.schedulerThread);
|
||||||
taskPool = new Timer("Timered task worker thread", true);
|
|
||||||
launcherLibraries = directories.launcherLibrariesDir;
|
launcherLibraries = directories.launcherLibrariesDir;
|
||||||
launcherLibrariesCompile = directories.launcherLibrariesCompileDir;
|
launcherLibrariesCompile = directories.launcherLibrariesCompileDir;
|
||||||
|
|
||||||
|
@ -247,18 +233,10 @@ public void invoke(String... args) throws Exception {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
switch (args[0]) {
|
switch (args[0]) {
|
||||||
case "full":
|
case "full" -> reload(ReloadType.FULL);
|
||||||
reload(ReloadType.FULL);
|
case "no_auth" -> reload(ReloadType.NO_AUTH);
|
||||||
break;
|
case "no_components" -> reload(ReloadType.NO_COMPONENTS);
|
||||||
case "no_auth":
|
default -> reload(ReloadType.FULL);
|
||||||
reload(ReloadType.NO_AUTH);
|
|
||||||
break;
|
|
||||||
case "no_components":
|
|
||||||
reload(ReloadType.NO_COMPONENTS);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
reload(ReloadType.FULL);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -282,14 +260,7 @@ public void invoke(String... args) throws Exception {
|
||||||
logger.error("Pair not found");
|
logger.error("Pair not found");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (pair.isUseCore()) {
|
|
||||||
pair.core.close();
|
pair.core.close();
|
||||||
} else {
|
|
||||||
pair.provider.close();
|
|
||||||
pair.handler.close();
|
|
||||||
pair.handler = null;
|
|
||||||
pair.provider = null;
|
|
||||||
}
|
|
||||||
pair.core = new RejectAuthCoreProvider();
|
pair.core = new RejectAuthCoreProvider();
|
||||||
pair.core.init(instance);
|
pair.core.init(instance);
|
||||||
}
|
}
|
||||||
|
@ -341,16 +312,6 @@ public void setProfiles(Set<ClientProfile> profilesList) {
|
||||||
this.profilesList = Collections.unmodifiableSet(profilesList);
|
this.profilesList = Collections.unmodifiableSet(profilesList);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public HashedDir getUpdateDir(String name) {
|
|
||||||
return updatesDirMap.get(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public Set<Entry<String, HashedDir>> getUpdateDirs() {
|
|
||||||
return updatesDirMap.entrySet();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void rebindNettyServerSocket() {
|
public void rebindNettyServerSocket() {
|
||||||
nettyServerSocketHandler.close();
|
nettyServerSocketHandler.close();
|
||||||
CommonHelper.newThread("Netty Server Socket Thread", false, nettyServerSocketHandler).start();
|
CommonHelper.newThread("Netty Server Socket Thread", false, nettyServerSocketHandler).start();
|
||||||
|
@ -445,6 +406,7 @@ public void restart() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
public void registerObject(String name, Object object) {
|
public void registerObject(String name, Object object) {
|
||||||
if (object instanceof Reconfigurable) {
|
if (object instanceof Reconfigurable) {
|
||||||
reconfigurableManager.registerReconfigurable(name, (Reconfigurable) object);
|
reconfigurableManager.registerReconfigurable(name, (Reconfigurable) object);
|
||||||
|
@ -454,6 +416,7 @@ public void registerObject(String name, Object object) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
public void unregisterObject(String name, Object object) {
|
public void unregisterObject(String name, Object object) {
|
||||||
if (object instanceof Reconfigurable) {
|
if (object instanceof Reconfigurable) {
|
||||||
reconfigurableManager.unregisterReconfigurable(name);
|
reconfigurableManager.unregisterReconfigurable(name);
|
||||||
|
|
|
@ -11,17 +11,14 @@
|
||||||
import pro.gravit.launcher.request.auth.AuthRequest;
|
import pro.gravit.launcher.request.auth.AuthRequest;
|
||||||
import pro.gravit.launcher.request.auth.GetAvailabilityAuthRequest;
|
import pro.gravit.launcher.request.auth.GetAvailabilityAuthRequest;
|
||||||
import pro.gravit.launchserver.auth.core.AuthCoreProvider;
|
import pro.gravit.launchserver.auth.core.AuthCoreProvider;
|
||||||
import pro.gravit.launchserver.auth.handler.AuthHandler;
|
|
||||||
import pro.gravit.launchserver.auth.password.PasswordVerifier;
|
import pro.gravit.launchserver.auth.password.PasswordVerifier;
|
||||||
import pro.gravit.launchserver.auth.protect.ProtectHandler;
|
import pro.gravit.launchserver.auth.protect.ProtectHandler;
|
||||||
import pro.gravit.launchserver.auth.protect.hwid.HWIDProvider;
|
import pro.gravit.launchserver.auth.protect.hwid.HWIDProvider;
|
||||||
import pro.gravit.launchserver.auth.provider.AuthProvider;
|
|
||||||
import pro.gravit.launchserver.auth.session.SessionStorage;
|
import pro.gravit.launchserver.auth.session.SessionStorage;
|
||||||
import pro.gravit.launchserver.auth.texture.TextureProvider;
|
import pro.gravit.launchserver.auth.texture.TextureProvider;
|
||||||
import pro.gravit.launchserver.components.Component;
|
import pro.gravit.launchserver.components.Component;
|
||||||
import pro.gravit.launchserver.config.LaunchServerConfig;
|
import pro.gravit.launchserver.config.LaunchServerConfig;
|
||||||
import pro.gravit.launchserver.config.LaunchServerRuntimeConfig;
|
import pro.gravit.launchserver.config.LaunchServerRuntimeConfig;
|
||||||
import pro.gravit.launchserver.dao.provider.DaoProvider;
|
|
||||||
import pro.gravit.launchserver.manangers.CertificateManager;
|
import pro.gravit.launchserver.manangers.CertificateManager;
|
||||||
import pro.gravit.launchserver.manangers.LaunchServerGsonManager;
|
import pro.gravit.launchserver.manangers.LaunchServerGsonManager;
|
||||||
import pro.gravit.launchserver.modules.impl.LaunchServerModulesManager;
|
import pro.gravit.launchserver.modules.impl.LaunchServerModulesManager;
|
||||||
|
@ -85,9 +82,6 @@ public static void main(String[] args) throws Exception {
|
||||||
logger.warn("LaunchServer signed incorrectly. Status: {}", result.type.name());
|
logger.warn("LaunchServer signed incorrectly. Status: {}", result.type.name());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (JVMHelper.getVersion() < 17) {
|
|
||||||
logger.warn("LaunchServer will end Java {} support in next release. Please install Java 17 or above", JVMHelper.getVersion());
|
|
||||||
}
|
|
||||||
|
|
||||||
LaunchServerRuntimeConfig runtimeConfig;
|
LaunchServerRuntimeConfig runtimeConfig;
|
||||||
LaunchServerConfig config;
|
LaunchServerConfig config;
|
||||||
|
@ -204,13 +198,10 @@ public static void initGson(LaunchServerModulesManager modulesManager) {
|
||||||
public static void registerAll() {
|
public static void registerAll() {
|
||||||
AuthCoreProvider.registerProviders();
|
AuthCoreProvider.registerProviders();
|
||||||
PasswordVerifier.registerProviders();
|
PasswordVerifier.registerProviders();
|
||||||
AuthHandler.registerHandlers();
|
|
||||||
AuthProvider.registerProviders();
|
|
||||||
TextureProvider.registerProviders();
|
TextureProvider.registerProviders();
|
||||||
Component.registerComponents();
|
Component.registerComponents();
|
||||||
ProtectHandler.registerHandlers();
|
ProtectHandler.registerHandlers();
|
||||||
WebSocketService.registerResponses();
|
WebSocketService.registerResponses();
|
||||||
DaoProvider.registerProviders();
|
|
||||||
AuthRequest.registerProviders();
|
AuthRequest.registerProviders();
|
||||||
GetAvailabilityAuthRequest.registerProviders();
|
GetAvailabilityAuthRequest.registerProviders();
|
||||||
HWIDProvider.registerProviders();
|
HWIDProvider.registerProviders();
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
package pro.gravit.launchserver.auth;
|
package pro.gravit.launchserver.auth;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
import pro.gravit.launchserver.LaunchServer;
|
import pro.gravit.launchserver.LaunchServer;
|
||||||
import pro.gravit.launchserver.auth.core.AuthCoreProvider;
|
import pro.gravit.launchserver.auth.core.AuthCoreProvider;
|
||||||
import pro.gravit.launchserver.auth.core.AuthSocialProvider;
|
import pro.gravit.launchserver.auth.core.AuthSocialProvider;
|
||||||
import pro.gravit.launchserver.auth.handler.AuthHandler;
|
import pro.gravit.launchserver.auth.core.MySQLCoreProvider;
|
||||||
import pro.gravit.launchserver.auth.provider.AuthProvider;
|
|
||||||
import pro.gravit.launchserver.auth.texture.TextureProvider;
|
import pro.gravit.launchserver.auth.texture.TextureProvider;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -13,22 +14,16 @@
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public final class AuthProviderPair {
|
public final class AuthProviderPair {
|
||||||
|
private transient final Logger logger = LogManager.getLogger();
|
||||||
public boolean isDefault = true;
|
public boolean isDefault = true;
|
||||||
public AuthCoreProvider core;
|
public AuthCoreProvider core;
|
||||||
public AuthSocialProvider social;
|
public AuthSocialProvider social;
|
||||||
public AuthProvider provider;
|
|
||||||
public AuthHandler handler;
|
|
||||||
public TextureProvider textureProvider;
|
public TextureProvider textureProvider;
|
||||||
public Map<String, String> links;
|
public Map<String, String> links;
|
||||||
public transient String name;
|
public transient String name;
|
||||||
public transient Set<String> features;
|
public transient Set<String> features;
|
||||||
public String displayName;
|
public String displayName;
|
||||||
|
private transient boolean warnOAuthShow = false;
|
||||||
public AuthProviderPair(AuthProvider provider, AuthHandler handler, TextureProvider textureProvider) {
|
|
||||||
this.provider = provider;
|
|
||||||
this.handler = handler;
|
|
||||||
this.textureProvider = textureProvider;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AuthProviderPair(AuthCoreProvider core, TextureProvider textureProvider) {
|
public AuthProviderPair(AuthCoreProvider core, TextureProvider textureProvider) {
|
||||||
this.core = core;
|
this.core = core;
|
||||||
|
@ -52,6 +47,15 @@ public static Set<String> getFeatures(Class<?> clazz) {
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void internalShowOAuthWarnMessage() {
|
||||||
|
if(!warnOAuthShow) {
|
||||||
|
if(!(core instanceof MySQLCoreProvider)) { // MySQL upgraded later
|
||||||
|
logger.warn("AuthCoreProvider {} ({}) not supported OAuth. Legacy session system may be removed in next release", name, core.getClass().getName());
|
||||||
|
}
|
||||||
|
warnOAuthShow = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void getFeatures(Class<?> clazz, Set<String> list) {
|
public static void getFeatures(Class<?> clazz, Set<String> list) {
|
||||||
Features features = clazz.getAnnotation(Features.class);
|
Features features = clazz.getAnnotation(Features.class);
|
||||||
if (features != null) {
|
if (features != null) {
|
||||||
|
@ -80,16 +84,6 @@ public final <T> T isSupport(Class<T> clazz) {
|
||||||
public final void init(LaunchServer srv, String name) {
|
public final void init(LaunchServer srv, String name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
if (links != null) link(srv);
|
if (links != null) link(srv);
|
||||||
if (core == null) {
|
|
||||||
if (provider == null) throw new NullPointerException(String.format("Auth %s provider null", name));
|
|
||||||
if (handler == null) throw new NullPointerException(String.format("Auth %s handler null", name));
|
|
||||||
if (social != null)
|
|
||||||
throw new IllegalArgumentException(String.format("Auth %s social can't be used in provider/handler method", name));
|
|
||||||
provider.init(srv);
|
|
||||||
handler.init(srv);
|
|
||||||
} else {
|
|
||||||
if (provider != null) throw new IllegalArgumentException(String.format("Auth %s provider not null", name));
|
|
||||||
if (handler != null) throw new IllegalArgumentException(String.format("Auth %s handler not null", name));
|
|
||||||
core.init(srv);
|
core.init(srv);
|
||||||
features = new HashSet<>();
|
features = new HashSet<>();
|
||||||
getFeatures(core.getClass(), features);
|
getFeatures(core.getClass(), features);
|
||||||
|
@ -98,7 +92,6 @@ public final void init(LaunchServer srv, String name) {
|
||||||
getFeatures(social.getClass(), features);
|
getFeatures(social.getClass(), features);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public final void link(LaunchServer srv) {
|
public final void link(LaunchServer srv) {
|
||||||
links.forEach((k, v) -> {
|
links.forEach((k, v) -> {
|
||||||
|
@ -106,19 +99,7 @@ public final void link(LaunchServer srv) {
|
||||||
if (pair == null) {
|
if (pair == null) {
|
||||||
throw new NullPointerException(String.format("Auth %s link failed. Pair %s not found", name, v));
|
throw new NullPointerException(String.format("Auth %s link failed. Pair %s not found", name, v));
|
||||||
}
|
}
|
||||||
if ("provider".equals(k)) {
|
if ("core".equals(k)) {
|
||||||
if (pair.provider == null)
|
|
||||||
throw new NullPointerException(String.format("Auth %s link failed. %s.provider is null", name, v));
|
|
||||||
provider = pair.provider;
|
|
||||||
} else if ("handler".equals(k)) {
|
|
||||||
if (pair.handler == null)
|
|
||||||
throw new NullPointerException(String.format("Auth %s link failed. %s.handler is null", name, v));
|
|
||||||
handler = pair.handler;
|
|
||||||
} else if ("textureProvider".equals(k)) {
|
|
||||||
if (pair.textureProvider == null)
|
|
||||||
throw new NullPointerException(String.format("Auth %s link failed. %s.textureProvider is null", name, v));
|
|
||||||
textureProvider = pair.textureProvider;
|
|
||||||
} else if ("core".equals(k)) {
|
|
||||||
if (pair.core == null)
|
if (pair.core == null)
|
||||||
throw new NullPointerException(String.format("Auth %s link failed. %s.core is null", name, v));
|
throw new NullPointerException(String.format("Auth %s link failed. %s.core is null", name, v));
|
||||||
core = pair.core;
|
core = pair.core;
|
||||||
|
@ -130,26 +111,13 @@ public final void close() throws IOException {
|
||||||
if (social != null) {
|
if (social != null) {
|
||||||
social.close();
|
social.close();
|
||||||
}
|
}
|
||||||
if (core == null) {
|
|
||||||
provider.close();
|
|
||||||
handler.close();
|
|
||||||
} else {
|
|
||||||
core.close();
|
core.close();
|
||||||
}
|
|
||||||
if (textureProvider != null) {
|
if (textureProvider != null) {
|
||||||
textureProvider.close();
|
textureProvider.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public final boolean isUseCore() {
|
|
||||||
return core != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public final boolean isUseSocial() {
|
public final boolean isUseSocial() {
|
||||||
return core != null && social != null;
|
return core != null && social != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final boolean isUseProviderAndHandler() {
|
|
||||||
return !isUseCore();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
package pro.gravit.launchserver.auth;
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public interface RequiredDAO {
|
|
||||||
}
|
|
|
@ -1,5 +1,6 @@
|
||||||
package pro.gravit.launchserver.auth.core;
|
package pro.gravit.launchserver.auth.core;
|
||||||
|
|
||||||
|
import com.google.gson.reflect.TypeToken;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import pro.gravit.launcher.Launcher;
|
import pro.gravit.launcher.Launcher;
|
||||||
|
@ -14,6 +15,7 @@
|
||||||
import pro.gravit.launchserver.auth.core.interfaces.UserHardware;
|
import pro.gravit.launchserver.auth.core.interfaces.UserHardware;
|
||||||
import pro.gravit.launchserver.auth.core.interfaces.provider.AuthSupportGetAllUsers;
|
import pro.gravit.launchserver.auth.core.interfaces.provider.AuthSupportGetAllUsers;
|
||||||
import pro.gravit.launchserver.auth.core.interfaces.provider.AuthSupportHardware;
|
import pro.gravit.launchserver.auth.core.interfaces.provider.AuthSupportHardware;
|
||||||
|
import pro.gravit.launchserver.auth.core.interfaces.provider.AuthSupportRegistration;
|
||||||
import pro.gravit.launchserver.auth.core.interfaces.user.UserSupportHardware;
|
import pro.gravit.launchserver.auth.core.interfaces.user.UserSupportHardware;
|
||||||
import pro.gravit.launchserver.auth.protect.hwid.HWIDProvider;
|
import pro.gravit.launchserver.auth.protect.hwid.HWIDProvider;
|
||||||
import pro.gravit.launchserver.manangers.AuthManager;
|
import pro.gravit.launchserver.manangers.AuthManager;
|
||||||
|
@ -25,6 +27,7 @@
|
||||||
import pro.gravit.utils.command.SubCommand;
|
import pro.gravit.utils.command.SubCommand;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -93,7 +96,7 @@ public void invoke(String... args) throws Exception {
|
||||||
if (report.success) {
|
if (report.success) {
|
||||||
logger.info("Password correct");
|
logger.info("Password correct");
|
||||||
} else {
|
} else {
|
||||||
if (report.needMoreFactor) {
|
if (report.needMoreFactors) {
|
||||||
if (report.factors.size() == 1 && report.factors.get(0) == -1) {
|
if (report.factors.size() == 1 && report.factors.get(0) == -1) {
|
||||||
logger.info("Password not correct: Required 2FA");
|
logger.info("Password not correct: Required 2FA");
|
||||||
} else {
|
} else {
|
||||||
|
@ -145,13 +148,13 @@ public void invoke(String... args) throws Exception {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (report.isUsingOAuth()) {
|
if (report.isUsingOAuth()) {
|
||||||
logger.info("OAuth: AccessToken: {} RefreshToken: {} MinecraftAccessToken: {}", report.oauthAccessToken, report.oauthRefreshToken, report.minecraftAccessToken);
|
logger.info("OAuth: AccessToken: {} RefreshToken: {} MinecraftAccessToken: {}", report.oauthAccessToken(), report.oauthRefreshToken(), report.minecraftAccessToken());
|
||||||
if (report.session != null) {
|
if (report.session() != null) {
|
||||||
logger.info("UserSession: id {} expire {} user {}", report.session.getID(), report.session.getExpireIn(), report.session.getUser() == null ? "null" : "found");
|
logger.info("UserSession: id {} expire {} user {}", report.session().getID(), report.session().getExpireIn(), report.session().getUser() == null ? "null" : "found");
|
||||||
logger.info(report.session.toString());
|
logger.info(report.session().toString());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
logger.info("Basic: MinecraftAccessToken: {}", report.minecraftAccessToken);
|
logger.info("Basic: MinecraftAccessToken: {}", report.minecraftAccessToken());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -281,6 +284,33 @@ public void invoke(String... args) throws Exception {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
var instance = isSupport(AuthSupportRegistration.class);
|
||||||
|
if (instance != null) {
|
||||||
|
map.put("register", new SubCommand("[username] [email] [plain or json password] (json args)", "Register new user") {
|
||||||
|
@Override
|
||||||
|
public void invoke(String... args) throws Exception {
|
||||||
|
verifyArgs(args, 2);
|
||||||
|
Map<String, String> map = null;
|
||||||
|
String username = args[0];
|
||||||
|
String email = args[1];
|
||||||
|
String plainPassword = args[2];
|
||||||
|
if (args.length > 3) {
|
||||||
|
Type typeOfMap = new TypeToken<Map<String, String>>() {
|
||||||
|
}.getType();
|
||||||
|
map = Launcher.gsonManager.gson.fromJson(args[2], typeOfMap);
|
||||||
|
}
|
||||||
|
AuthRequest.AuthPasswordInterface password;
|
||||||
|
if (plainPassword.startsWith("{")) {
|
||||||
|
password = Launcher.gsonManager.gson.fromJson(plainPassword, AuthRequest.AuthPasswordInterface.class);
|
||||||
|
} else {
|
||||||
|
password = new AuthPlainPassword(plainPassword);
|
||||||
|
}
|
||||||
|
instance.registration(username, email, password, map);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -315,30 +345,30 @@ public static class PasswordVerifyReport {
|
||||||
public static final PasswordVerifyReport FAILED = new PasswordVerifyReport(false);
|
public static final PasswordVerifyReport FAILED = new PasswordVerifyReport(false);
|
||||||
public static final PasswordVerifyReport OK = new PasswordVerifyReport(true);
|
public static final PasswordVerifyReport OK = new PasswordVerifyReport(true);
|
||||||
public final boolean success;
|
public final boolean success;
|
||||||
public final boolean needMoreFactor;
|
public final boolean needMoreFactors;
|
||||||
public final List<Integer> factors;
|
public final List<Integer> factors;
|
||||||
|
|
||||||
public PasswordVerifyReport(boolean success) {
|
public PasswordVerifyReport(boolean success) {
|
||||||
this.success = success;
|
this.success = success;
|
||||||
this.needMoreFactor = false;
|
this.needMoreFactors = false;
|
||||||
this.factors = List.of();
|
this.factors = List.of();
|
||||||
}
|
}
|
||||||
|
|
||||||
public PasswordVerifyReport(int nextFactor) {
|
public PasswordVerifyReport(int nextFactor) {
|
||||||
this.success = false;
|
this.success = false;
|
||||||
this.needMoreFactor = true;
|
this.needMoreFactors = true;
|
||||||
this.factors = List.of(nextFactor);
|
this.factors = List.of(nextFactor);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PasswordVerifyReport(List<Integer> factors) {
|
public PasswordVerifyReport(List<Integer> factors) {
|
||||||
this.success = false;
|
this.success = false;
|
||||||
this.needMoreFactor = false;
|
this.needMoreFactors = false;
|
||||||
this.factors = Collections.unmodifiableList(factors);
|
this.factors = Collections.unmodifiableList(factors);
|
||||||
}
|
}
|
||||||
|
|
||||||
private PasswordVerifyReport(boolean success, boolean needMoreFactor, List<Integer> factors) {
|
private PasswordVerifyReport(boolean success, boolean needMoreFactors, List<Integer> factors) {
|
||||||
this.success = success;
|
this.success = success;
|
||||||
this.needMoreFactor = needMoreFactor;
|
this.needMoreFactors = needMoreFactors;
|
||||||
this.factors = factors;
|
this.factors = factors;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,78 +0,0 @@
|
||||||
package pro.gravit.launchserver.auth.handler;
|
|
||||||
|
|
||||||
import pro.gravit.launchserver.LaunchServer;
|
|
||||||
import pro.gravit.launchserver.auth.AuthException;
|
|
||||||
import pro.gravit.launchserver.auth.provider.AuthProviderResult;
|
|
||||||
import pro.gravit.utils.ProviderMap;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
|
|
||||||
public abstract class AuthHandler implements AutoCloseable {
|
|
||||||
public static final ProviderMap<AuthHandler> providers = new ProviderMap<>("AuthHandler");
|
|
||||||
private static boolean registredHandl = false;
|
|
||||||
protected transient LaunchServer srv;
|
|
||||||
|
|
||||||
public static UUID authError(String message) throws AuthException {
|
|
||||||
throw new AuthException(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public static void registerHandlers() {
|
|
||||||
if (!registredHandl) {
|
|
||||||
providers.register("null", NullAuthHandler.class);
|
|
||||||
providers.register("json", JsonAuthHandler.class);
|
|
||||||
providers.register("memory", MemoryAuthHandler.class);
|
|
||||||
providers.register("mysql", MySQLAuthHandler.class);
|
|
||||||
providers.register("postgresql", PostgreSQLAuthHandler.class);
|
|
||||||
providers.register("request", RequestAuthHandler.class);
|
|
||||||
providers.register("hibernate", HibernateAuthHandler.class);
|
|
||||||
registredHandl = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the UUID associated with the account
|
|
||||||
*
|
|
||||||
* @param authResult {@link pro.gravit.launchserver.auth.provider.AuthProvider} result
|
|
||||||
* @return User UUID
|
|
||||||
* @throws IOException Internal Script Error
|
|
||||||
*/
|
|
||||||
public abstract UUID auth(AuthProviderResult authResult) throws IOException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validates serverID
|
|
||||||
*
|
|
||||||
* @param username user name
|
|
||||||
* @param serverID serverID to check
|
|
||||||
* @return user UUID
|
|
||||||
* @throws IOException Internal Script Error
|
|
||||||
*/
|
|
||||||
public abstract UUID checkServer(String username, String serverID) throws IOException;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public abstract void close() throws IOException;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks assessToken for validity and saves serverID if successful
|
|
||||||
*
|
|
||||||
* @param username user name
|
|
||||||
* @param accessToken assessToken to check
|
|
||||||
* @param serverID serverID to save
|
|
||||||
* @return true - allow, false - deny
|
|
||||||
* @throws IOException Internal Script Error
|
|
||||||
*/
|
|
||||||
public abstract boolean joinServer(String username, String accessToken, String serverID) throws IOException;
|
|
||||||
|
|
||||||
|
|
||||||
public abstract UUID usernameToUUID(String username) throws IOException;
|
|
||||||
|
|
||||||
|
|
||||||
public abstract String uuidToUsername(UUID uuid) throws IOException;
|
|
||||||
|
|
||||||
public void init(LaunchServer srv) {
|
|
||||||
this.srv = srv;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,206 +0,0 @@
|
||||||
package pro.gravit.launchserver.auth.handler;
|
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
import pro.gravit.launcher.Launcher;
|
|
||||||
import pro.gravit.launcher.NeedGarbageCollection;
|
|
||||||
import pro.gravit.launchserver.Reconfigurable;
|
|
||||||
import pro.gravit.launchserver.auth.provider.AuthProviderResult;
|
|
||||||
import pro.gravit.utils.command.Command;
|
|
||||||
import pro.gravit.utils.command.SubCommand;
|
|
||||||
import pro.gravit.utils.helper.CommonHelper;
|
|
||||||
import pro.gravit.utils.helper.IOHelper;
|
|
||||||
import pro.gravit.utils.helper.SecurityHelper;
|
|
||||||
import pro.gravit.utils.helper.VerifyHelper;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.Reader;
|
|
||||||
import java.io.Writer;
|
|
||||||
import java.nio.file.Paths;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public abstract class CachedAuthHandler extends AuthHandler implements NeedGarbageCollection, Reconfigurable {
|
|
||||||
private transient final Map<UUID, Entry> entryCache = new HashMap<>(1024);
|
|
||||||
private transient final Map<String, UUID> usernamesCache = new HashMap<>(1024);
|
|
||||||
private transient final Logger logger = LogManager.getLogger();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, Command> getCommands() {
|
|
||||||
Map<String, Command> commands = new HashMap<>();
|
|
||||||
commands.put("clear", new SubCommand() {
|
|
||||||
@Override
|
|
||||||
public void invoke(String... args) {
|
|
||||||
long entryCacheSize = entryCache.size();
|
|
||||||
long usernamesCacheSize = usernamesCache.size();
|
|
||||||
entryCache.clear();
|
|
||||||
usernamesCache.clear();
|
|
||||||
logger.info("Cleared cache: {} Entry {} Usernames", entryCacheSize, usernamesCacheSize);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
commands.put("load", new SubCommand() {
|
|
||||||
@Override
|
|
||||||
public void invoke(String... args) throws Exception {
|
|
||||||
verifyArgs(args, 2);
|
|
||||||
|
|
||||||
logger.info("CachedAuthHandler read from {}", args[0]);
|
|
||||||
int size_entry;
|
|
||||||
int size_username;
|
|
||||||
try (Reader reader = IOHelper.newReader(Paths.get(args[1]))) {
|
|
||||||
EntryAndUsername entryAndUsername = Launcher.gsonManager.configGson.fromJson(reader, EntryAndUsername.class);
|
|
||||||
size_entry = entryAndUsername.entryCache.size();
|
|
||||||
size_username = entryAndUsername.usernameCache.size();
|
|
||||||
loadEntryCache(entryAndUsername.entryCache);
|
|
||||||
loadUsernameCache(entryAndUsername.usernameCache);
|
|
||||||
|
|
||||||
}
|
|
||||||
logger.info("Read {} entryCache {} usernameCache", size_entry, size_username);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
commands.put("unload", new SubCommand() {
|
|
||||||
@Override
|
|
||||||
public void invoke(String... args) throws Exception {
|
|
||||||
verifyArgs(args, 2);
|
|
||||||
|
|
||||||
logger.info("CachedAuthHandler write to {}", args[1]);
|
|
||||||
Map<UUID, CachedAuthHandler.Entry> entryCache = getEntryCache();
|
|
||||||
Map<String, UUID> usernamesCache = getUsernamesCache();
|
|
||||||
EntryAndUsername serializable = new EntryAndUsername();
|
|
||||||
serializable.entryCache = entryCache;
|
|
||||||
serializable.usernameCache = usernamesCache;
|
|
||||||
try (Writer writer = IOHelper.newWriter(Paths.get(args[1]))) {
|
|
||||||
Launcher.gsonManager.configGson.toJson(serializable, writer);
|
|
||||||
}
|
|
||||||
logger.info("Write {} entryCache, {} usernameCache", entryCache.size(), usernamesCache.size());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return commands;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void addEntry(Entry entry) {
|
|
||||||
Entry previous = entryCache.put(entry.uuid, entry);
|
|
||||||
if (previous != null)
|
|
||||||
usernamesCache.remove(CommonHelper.low(previous.username));
|
|
||||||
usernamesCache.put(CommonHelper.low(entry.username), entry.uuid);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final synchronized UUID auth(AuthProviderResult result) throws IOException {
|
|
||||||
Entry entry = getEntry(result.username);
|
|
||||||
if (entry == null || !updateAuth(entry.uuid, entry.username, result.accessToken))
|
|
||||||
return authError(String.format("UUID is null for username '%s'", result.username));
|
|
||||||
|
|
||||||
// Update cached access token (and username case)
|
|
||||||
entry.username = result.username;
|
|
||||||
entry.accessToken = result.accessToken;
|
|
||||||
entry.serverID = null;
|
|
||||||
return entry.uuid;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public synchronized UUID checkServer(String username, String serverID) throws IOException {
|
|
||||||
Entry entry = getEntry(username);
|
|
||||||
return entry != null && username.equals(entry.username) &&
|
|
||||||
serverID.equals(entry.serverID) ? entry.uuid : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract Entry fetchEntry(String username) throws IOException;
|
|
||||||
|
|
||||||
protected abstract Entry fetchEntry(UUID uuid) throws IOException;
|
|
||||||
|
|
||||||
private Entry getEntry(String username) throws IOException {
|
|
||||||
UUID uuid = usernamesCache.get(CommonHelper.low(username));
|
|
||||||
if (uuid != null)
|
|
||||||
return getEntry(uuid);
|
|
||||||
|
|
||||||
// Fetch entry by username
|
|
||||||
Entry entry = fetchEntry(username);
|
|
||||||
if (entry != null)
|
|
||||||
addEntry(entry);
|
|
||||||
|
|
||||||
// Return what we got
|
|
||||||
return entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Entry getEntry(UUID uuid) throws IOException {
|
|
||||||
Entry entry = entryCache.get(uuid);
|
|
||||||
if (entry == null) {
|
|
||||||
entry = fetchEntry(uuid);
|
|
||||||
if (entry != null)
|
|
||||||
addEntry(entry);
|
|
||||||
}
|
|
||||||
return entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public synchronized boolean joinServer(String username, String accessToken, String serverID) throws IOException {
|
|
||||||
Entry entry = getEntry(username);
|
|
||||||
if (entry == null || !username.equals(entry.username) || !accessToken.equals(entry.accessToken) ||
|
|
||||||
!updateServerID(entry.uuid, serverID))
|
|
||||||
return false; // Account doesn't exist or invalid access token
|
|
||||||
|
|
||||||
// Update cached server ID
|
|
||||||
entry.serverID = serverID;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void garbageCollection() {
|
|
||||||
entryCache.clear();
|
|
||||||
usernamesCache.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<UUID, Entry> getEntryCache() {
|
|
||||||
return entryCache;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, UUID> getUsernamesCache() {
|
|
||||||
return usernamesCache;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void loadEntryCache(Map<UUID, Entry> map) {
|
|
||||||
entryCache.putAll(map);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void loadUsernameCache(Map<String, UUID> map) {
|
|
||||||
usernamesCache.putAll(map);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract boolean updateAuth(UUID uuid, String username, String accessToken) throws IOException;
|
|
||||||
|
|
||||||
protected abstract boolean updateServerID(UUID uuid, String serverID) throws IOException;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final synchronized UUID usernameToUUID(String username) throws IOException {
|
|
||||||
Entry entry = getEntry(username);
|
|
||||||
return entry == null ? null : entry.uuid;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final synchronized String uuidToUsername(UUID uuid) throws IOException {
|
|
||||||
Entry entry = getEntry(uuid);
|
|
||||||
return entry == null ? null : entry.username;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final class Entry {
|
|
||||||
|
|
||||||
public final UUID uuid;
|
|
||||||
private String username;
|
|
||||||
private String accessToken;
|
|
||||||
private String serverID;
|
|
||||||
|
|
||||||
|
|
||||||
public Entry(UUID uuid, String username, String accessToken, String serverID) {
|
|
||||||
this.uuid = Objects.requireNonNull(uuid, "uuid");
|
|
||||||
this.username = Objects.requireNonNull(username, "username");
|
|
||||||
this.accessToken = accessToken == null ? null : SecurityHelper.verifyToken(accessToken);
|
|
||||||
this.serverID = serverID == null ? null : VerifyHelper.verifyServerID(serverID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static class EntryAndUsername {
|
|
||||||
public Map<UUID, CachedAuthHandler.Entry> entryCache;
|
|
||||||
public Map<String, UUID> usernameCache;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
package pro.gravit.launchserver.auth.handler;
|
|
||||||
|
|
||||||
import pro.gravit.launchserver.auth.RequiredDAO;
|
|
||||||
import pro.gravit.launchserver.dao.User;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public class HibernateAuthHandler extends CachedAuthHandler implements RequiredDAO {
|
|
||||||
@Override
|
|
||||||
protected Entry fetchEntry(String username) {
|
|
||||||
User user = srv.config.dao.userDAO.findByUsername(username);
|
|
||||||
if (user == null) return null;
|
|
||||||
return new Entry(user.getUuid(), user.getUsername(), user.getAccessToken(), user.getServerID());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Entry fetchEntry(UUID uuid) {
|
|
||||||
User user = srv.config.dao.userDAO.findByUUID(uuid);
|
|
||||||
if (user == null) return null;
|
|
||||||
return new Entry(user.getUuid(), user.getUsername(), user.getAccessToken(), user.getServerID());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean updateAuth(UUID uuid, String username, String accessToken) {
|
|
||||||
User user = srv.config.dao.userDAO.findByUUID(uuid);
|
|
||||||
user.setAccessToken(accessToken);
|
|
||||||
srv.config.dao.userDAO.update(user);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean updateServerID(UUID uuid, String serverID) {
|
|
||||||
User user = srv.config.dao.userDAO.findByUUID(uuid);
|
|
||||||
user.setServerID(serverID);
|
|
||||||
srv.config.dao.userDAO.update(user);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,90 +0,0 @@
|
||||||
package pro.gravit.launchserver.auth.handler;
|
|
||||||
|
|
||||||
import pro.gravit.launcher.HTTPRequest;
|
|
||||||
import pro.gravit.launcher.Launcher;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class JsonAuthHandler extends CachedAuthHandler {
|
|
||||||
public URL getUrl;
|
|
||||||
public URL updateAuthUrl;
|
|
||||||
public URL updateServerIdUrl;
|
|
||||||
public String apiKey;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Entry fetchEntry(String username) throws IOException {
|
|
||||||
return Launcher.gsonManager.gson.fromJson(HTTPRequest.jsonRequest(Launcher.gsonManager.gson.toJsonTree(new EntryRequestByUsername(username, apiKey)), getUrl), Entry.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Entry fetchEntry(UUID uuid) throws IOException {
|
|
||||||
return Launcher.gsonManager.gson.fromJson(HTTPRequest.jsonRequest(Launcher.gsonManager.gson.toJsonTree(new EntryRequestByUUID(uuid, apiKey)), getUrl), Entry.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean updateAuth(UUID uuid, String username, String accessToken) throws IOException {
|
|
||||||
return Launcher.gsonManager.gson.fromJson(HTTPRequest.jsonRequest(Launcher.gsonManager.gson.toJsonTree(new UpdateAuthRequest(uuid, username, accessToken, apiKey)), updateAuthUrl), SuccessResponse.class).success;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean updateServerID(UUID uuid, String serverID) throws IOException {
|
|
||||||
return Launcher.gsonManager.gson.fromJson(HTTPRequest.jsonRequest(Launcher.gsonManager.gson.toJsonTree(new UpdateServerIDRequest(uuid, serverID, apiKey)), updateServerIdUrl), SuccessResponse.class).success;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class EntryRequestByUsername {
|
|
||||||
public final String username;
|
|
||||||
public final String apiKey;
|
|
||||||
|
|
||||||
public EntryRequestByUsername(String username, String apiKey) {
|
|
||||||
this.username = username;
|
|
||||||
this.apiKey = apiKey;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class EntryRequestByUUID {
|
|
||||||
public final UUID uuid;
|
|
||||||
public final String apiKey;
|
|
||||||
|
|
||||||
public EntryRequestByUUID(UUID uuid, String apiKey) {
|
|
||||||
this.uuid = uuid;
|
|
||||||
this.apiKey = apiKey;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class UpdateAuthRequest {
|
|
||||||
public final UUID uuid;
|
|
||||||
public final String username;
|
|
||||||
public final String accessToken;
|
|
||||||
public final String apiKey;
|
|
||||||
|
|
||||||
public UpdateAuthRequest(UUID uuid, String username, String accessToken, String apiKey) {
|
|
||||||
this.uuid = uuid;
|
|
||||||
this.username = username;
|
|
||||||
this.accessToken = accessToken;
|
|
||||||
this.apiKey = apiKey;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class UpdateServerIDRequest {
|
|
||||||
public final UUID uuid;
|
|
||||||
public final String serverID;
|
|
||||||
public final String apiKey;
|
|
||||||
|
|
||||||
public UpdateServerIDRequest(UUID uuid, String serverID, String apiKey) {
|
|
||||||
this.uuid = uuid;
|
|
||||||
this.serverID = serverID;
|
|
||||||
this.apiKey = apiKey;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class SuccessResponse {
|
|
||||||
public boolean success;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,54 +0,0 @@
|
||||||
package pro.gravit.launchserver.auth.handler;
|
|
||||||
|
|
||||||
import pro.gravit.utils.helper.IOHelper;
|
|
||||||
import pro.gravit.utils.helper.VerifyHelper;
|
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public final class MemoryAuthHandler extends CachedAuthHandler {
|
|
||||||
private static String toUsername(UUID uuid) {
|
|
||||||
byte[] bytes = ByteBuffer.allocate(16).
|
|
||||||
putLong(uuid.getMostSignificantBits()).
|
|
||||||
putLong(uuid.getLeastSignificantBits()).array();
|
|
||||||
|
|
||||||
// Find username end
|
|
||||||
int length = 0;
|
|
||||||
while (length < bytes.length && bytes[length] != 0)
|
|
||||||
length++;
|
|
||||||
|
|
||||||
// Decode and verify
|
|
||||||
return VerifyHelper.verifyUsername(new String(bytes, 0, length, IOHelper.ASCII_CHARSET));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static UUID toUUID(String username) {
|
|
||||||
ByteBuffer buffer = ByteBuffer.wrap(Arrays.copyOf(IOHelper.encodeASCII(username), 16));
|
|
||||||
return new UUID(buffer.getLong(), buffer.getLong()); // MOST, LEAST
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
// Do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Entry fetchEntry(String username) {
|
|
||||||
return new Entry(toUUID(username), username, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Entry fetchEntry(UUID uuid) {
|
|
||||||
return new Entry(uuid, toUsername(uuid), null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean updateAuth(UUID uuid, String username, String accessToken) {
|
|
||||||
return true; // Do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean updateServerID(UUID uuid, String serverID) {
|
|
||||||
return true; // Do nothing
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,110 +0,0 @@
|
||||||
package pro.gravit.launchserver.auth.handler;
|
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
import pro.gravit.launchserver.LaunchServer;
|
|
||||||
import pro.gravit.launchserver.auth.MySQLSourceConfig;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.PreparedStatement;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public final class MySQLAuthHandler extends CachedAuthHandler {
|
|
||||||
private transient final Logger logger = LogManager.getLogger();
|
|
||||||
private MySQLSourceConfig mySQLHolder;
|
|
||||||
private String uuidColumn;
|
|
||||||
private String usernameColumn;
|
|
||||||
private String accessTokenColumn;
|
|
||||||
private String serverIDColumn;
|
|
||||||
private String table;
|
|
||||||
|
|
||||||
// Prepared SQL queries
|
|
||||||
private transient String queryByUUIDSQL;
|
|
||||||
private transient String queryByUsernameSQL;
|
|
||||||
private transient String updateAuthSQL;
|
|
||||||
private transient String updateServerIDSQL;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init(LaunchServer srv) {
|
|
||||||
super.init(srv);
|
|
||||||
//Verify
|
|
||||||
if (mySQLHolder == null) logger.error("mySQLHolder cannot be null");
|
|
||||||
if (uuidColumn == null) logger.error("uuidColumn cannot be null");
|
|
||||||
if (usernameColumn == null) logger.error("usernameColumn cannot be null");
|
|
||||||
if (accessTokenColumn == null) logger.error("accessTokenColumn cannot be null");
|
|
||||||
if (serverIDColumn == null) logger.error("serverIDColumn cannot be null");
|
|
||||||
if (table == null) logger.error("table cannot be null");
|
|
||||||
// Prepare SQL queries
|
|
||||||
queryByUUIDSQL = String.format("SELECT %s, %s, %s, %s FROM %s WHERE %s=? LIMIT 1",
|
|
||||||
uuidColumn, usernameColumn, accessTokenColumn, serverIDColumn, table, uuidColumn);
|
|
||||||
queryByUsernameSQL = String.format("SELECT %s, %s, %s, %s FROM %s WHERE %s=? LIMIT 1",
|
|
||||||
uuidColumn, usernameColumn, accessTokenColumn, serverIDColumn, table, usernameColumn);
|
|
||||||
updateAuthSQL = String.format("UPDATE %s SET %s=?, %s=?, %s=NULL WHERE %s=? LIMIT 1",
|
|
||||||
table, usernameColumn, accessTokenColumn, serverIDColumn, uuidColumn);
|
|
||||||
updateServerIDSQL = String.format("UPDATE %s SET %s=? WHERE %s=? LIMIT 1",
|
|
||||||
table, serverIDColumn, uuidColumn);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
mySQLHolder.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Entry constructEntry(ResultSet set) throws SQLException {
|
|
||||||
return set.next() ? new Entry(UUID.fromString(set.getString(uuidColumn)), set.getString(usernameColumn),
|
|
||||||
set.getString(accessTokenColumn), set.getString(serverIDColumn)) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Entry fetchEntry(String username) throws IOException {
|
|
||||||
return query(queryByUsernameSQL, username);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Entry fetchEntry(UUID uuid) throws IOException {
|
|
||||||
return query(queryByUUIDSQL, uuid.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
private Entry query(String sql, String value) throws IOException {
|
|
||||||
try (Connection c = mySQLHolder.getConnection()) {
|
|
||||||
PreparedStatement s = c.prepareStatement(sql);
|
|
||||||
s.setString(1, value);
|
|
||||||
s.setQueryTimeout(MySQLSourceConfig.TIMEOUT);
|
|
||||||
try (ResultSet set = s.executeQuery()) {
|
|
||||||
return constructEntry(set);
|
|
||||||
}
|
|
||||||
} catch (SQLException e) {
|
|
||||||
throw new IOException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean updateAuth(UUID uuid, String username, String accessToken) throws IOException {
|
|
||||||
try (Connection c = mySQLHolder.getConnection()) {
|
|
||||||
PreparedStatement s = c.prepareStatement(updateAuthSQL);
|
|
||||||
s.setString(1, username); // Username case
|
|
||||||
s.setString(2, accessToken);
|
|
||||||
s.setString(3, uuid.toString());
|
|
||||||
s.setQueryTimeout(MySQLSourceConfig.TIMEOUT);
|
|
||||||
return s.executeUpdate() > 0;
|
|
||||||
} catch (SQLException e) {
|
|
||||||
throw new IOException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean updateServerID(UUID uuid, String serverID) throws IOException {
|
|
||||||
try (Connection c = mySQLHolder.getConnection()) {
|
|
||||||
PreparedStatement s = c.prepareStatement(updateServerIDSQL);
|
|
||||||
s.setString(1, serverID);
|
|
||||||
s.setString(2, uuid.toString());
|
|
||||||
s.setQueryTimeout(MySQLSourceConfig.TIMEOUT);
|
|
||||||
return s.executeUpdate() > 0;
|
|
||||||
} catch (SQLException e) {
|
|
||||||
throw new IOException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,53 +0,0 @@
|
||||||
package pro.gravit.launchserver.auth.handler;
|
|
||||||
|
|
||||||
import pro.gravit.launchserver.auth.provider.AuthProviderResult;
|
|
||||||
import pro.gravit.utils.helper.VerifyHelper;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public final class NullAuthHandler extends AuthHandler {
|
|
||||||
private volatile AuthHandler handler;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UUID auth(AuthProviderResult authResult) throws IOException {
|
|
||||||
return getHandler().auth(authResult);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UUID checkServer(String username, String serverID) throws IOException {
|
|
||||||
return getHandler().checkServer(username, serverID);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() throws IOException {
|
|
||||||
AuthHandler handler = this.handler;
|
|
||||||
if (handler != null)
|
|
||||||
handler.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
private AuthHandler getHandler() {
|
|
||||||
return VerifyHelper.verify(handler, Objects::nonNull, "Backend auth handler wasn't set");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean joinServer(String username, String accessToken, String serverID) throws IOException {
|
|
||||||
return getHandler().joinServer(username, accessToken, serverID);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void setBackend(AuthHandler handler) {
|
|
||||||
this.handler = handler;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UUID usernameToUUID(String username) throws IOException {
|
|
||||||
return getHandler().usernameToUUID(username);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String uuidToUsername(UUID uuid) throws IOException {
|
|
||||||
return getHandler().uuidToUsername(uuid);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,118 +0,0 @@
|
||||||
package pro.gravit.launchserver.auth.handler;
|
|
||||||
|
|
||||||
import org.postgresql.util.PGobject;
|
|
||||||
import pro.gravit.launchserver.auth.PostgreSQLSourceConfig;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.PreparedStatement;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public final class PostgreSQLAuthHandler extends CachedAuthHandler {
|
|
||||||
private PostgreSQLSourceConfig postgreSQLHolder;
|
|
||||||
private String uuidColumn;
|
|
||||||
private String usernameColumn;
|
|
||||||
private String accessTokenColumn;
|
|
||||||
private String serverIDColumn;
|
|
||||||
|
|
||||||
|
|
||||||
private String queryByUUIDSQL;
|
|
||||||
private String queryByUsernameSQL;
|
|
||||||
private String updateAuthSQL;
|
|
||||||
private String updateServerIDSQL;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
postgreSQLHolder.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Entry constructEntry(ResultSet set) throws SQLException {
|
|
||||||
return set.next() ? new Entry(UUID.fromString(set.getString(uuidColumn)),
|
|
||||||
set.getString(usernameColumn), set.getString(accessTokenColumn), set.getString(serverIDColumn)) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Entry fetchEntry(String username) throws IOException {
|
|
||||||
return query(queryByUsernameSQL, username);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Entry fetchEntry(UUID uuid) throws IOException {
|
|
||||||
return query(queryByUUIDSQL, uuid);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean updateAuth(UUID uuid, String username, String accessToken) throws IOException {
|
|
||||||
try (Connection c = postgreSQLHolder.getConnection();
|
|
||||||
PreparedStatement s = c.prepareStatement(updateAuthSQL)) {
|
|
||||||
s.setString(1, username); // Username case
|
|
||||||
s.setString(2, accessToken);
|
|
||||||
|
|
||||||
PGobject uuidObject = new PGobject();
|
|
||||||
uuidObject.setType("uuid");
|
|
||||||
uuidObject.setValue(uuid.toString());
|
|
||||||
s.setObject(3, uuidObject);
|
|
||||||
|
|
||||||
// Execute update
|
|
||||||
s.setQueryTimeout(PostgreSQLSourceConfig.TIMEOUT);
|
|
||||||
return s.executeUpdate() > 0;
|
|
||||||
} catch (SQLException e) {
|
|
||||||
throw new IOException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean updateServerID(UUID uuid, String serverID) throws IOException {
|
|
||||||
try (Connection c = postgreSQLHolder.getConnection();
|
|
||||||
PreparedStatement s = c.prepareStatement(updateServerIDSQL)) {
|
|
||||||
s.setString(1, serverID);
|
|
||||||
|
|
||||||
PGobject uuidObject = new PGobject();
|
|
||||||
uuidObject.setType("uuid");
|
|
||||||
uuidObject.setValue(uuid.toString());
|
|
||||||
s.setObject(2, uuidObject);
|
|
||||||
|
|
||||||
// Execute update
|
|
||||||
s.setQueryTimeout(PostgreSQLSourceConfig.TIMEOUT);
|
|
||||||
return s.executeUpdate() > 0;
|
|
||||||
} catch (SQLException e) {
|
|
||||||
throw new IOException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Entry query(String sql, String value) throws IOException {
|
|
||||||
try (Connection c = postgreSQLHolder.getConnection();
|
|
||||||
PreparedStatement s = c.prepareStatement(sql)) {
|
|
||||||
s.setString(1, value);
|
|
||||||
|
|
||||||
// Execute query
|
|
||||||
s.setQueryTimeout(PostgreSQLSourceConfig.TIMEOUT);
|
|
||||||
try (ResultSet set = s.executeQuery()) {
|
|
||||||
return constructEntry(set);
|
|
||||||
}
|
|
||||||
} catch (SQLException e) {
|
|
||||||
throw new IOException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Entry query(String sql, UUID value) throws IOException {
|
|
||||||
try (Connection c = postgreSQLHolder.getConnection();
|
|
||||||
PreparedStatement s = c.prepareStatement(sql)) {
|
|
||||||
PGobject uuidObject = new PGobject();
|
|
||||||
uuidObject.setType("uuid");
|
|
||||||
uuidObject.setValue(value.toString());
|
|
||||||
|
|
||||||
s.setObject(1, uuidObject);
|
|
||||||
|
|
||||||
// Execute query
|
|
||||||
s.setQueryTimeout(PostgreSQLSourceConfig.TIMEOUT);
|
|
||||||
try (ResultSet set = s.executeQuery()) {
|
|
||||||
return constructEntry(set);
|
|
||||||
}
|
|
||||||
} catch (SQLException e) {
|
|
||||||
throw new IOException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,91 +0,0 @@
|
||||||
package pro.gravit.launchserver.auth.handler;
|
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
import pro.gravit.launchserver.LaunchServer;
|
|
||||||
import pro.gravit.utils.helper.CommonHelper;
|
|
||||||
import pro.gravit.utils.helper.IOHelper;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public final class RequestAuthHandler extends CachedAuthHandler {
|
|
||||||
private transient final Logger logger = LogManager.getLogger();
|
|
||||||
private final String splitSymbol = ":";
|
|
||||||
private final String goodResponse = "OK";
|
|
||||||
private String usernameFetch;
|
|
||||||
private String uuidFetch;
|
|
||||||
private String updateAuth;
|
|
||||||
private String updateServerID;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init(LaunchServer srv) {
|
|
||||||
super.init(srv);
|
|
||||||
if (usernameFetch == null)
|
|
||||||
logger.error("usernameFetch cannot be null");
|
|
||||||
if (uuidFetch == null)
|
|
||||||
logger.error("uuidFetch cannot be null");
|
|
||||||
if (updateAuth == null)
|
|
||||||
logger.error("updateAuth cannot be null");
|
|
||||||
if (updateServerID == null)
|
|
||||||
logger.error("updateServerID cannot be null");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Entry fetchEntry(UUID uuid) throws IOException {
|
|
||||||
String response = IOHelper.request(new URL(CommonHelper.replace(uuidFetch, "uuid", IOHelper.urlEncode(uuid.toString()))));
|
|
||||||
String[] parts = response.split(splitSymbol);
|
|
||||||
String username = parts[0];
|
|
||||||
String accessToken = parts[1];
|
|
||||||
String serverID = parts[2];
|
|
||||||
if (logger.isDebugEnabled()) {
|
|
||||||
logger.debug("[AuthHandler] Got username: " + username);
|
|
||||||
logger.debug("[AuthHandler] Got accessToken: " + accessToken);
|
|
||||||
logger.debug("[AuthHandler] Got serverID: " + serverID);
|
|
||||||
logger.debug("[AuthHandler] Got UUID: " + uuid);
|
|
||||||
}
|
|
||||||
return new Entry(uuid, username, accessToken, serverID);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Entry fetchEntry(String username) throws IOException {
|
|
||||||
String response = IOHelper.request(new URL(CommonHelper.replace(usernameFetch, "user", IOHelper.urlEncode(username))));
|
|
||||||
String[] parts = response.split(splitSymbol);
|
|
||||||
UUID uuid = UUID.fromString(parts[0]);
|
|
||||||
String accessToken = parts[1];
|
|
||||||
String serverID = parts[2];
|
|
||||||
if (logger.isDebugEnabled()) {
|
|
||||||
logger.debug("[AuthHandler] Got username: " + username);
|
|
||||||
logger.debug("[AuthHandler] Got accessToken: " + accessToken);
|
|
||||||
logger.debug("[AuthHandler] Got serverID: " + serverID);
|
|
||||||
logger.debug("[AuthHandler] Got UUID: " + uuid);
|
|
||||||
}
|
|
||||||
return new Entry(uuid, username, accessToken, serverID);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean updateAuth(UUID uuid, String username, String accessToken) throws IOException {
|
|
||||||
String response = IOHelper.request(new URL(CommonHelper.replace(updateAuth, "user", IOHelper.urlEncode(username), "uuid", IOHelper.urlEncode(uuid.toString()), "token", IOHelper.urlEncode(accessToken))));
|
|
||||||
if (logger.isDebugEnabled()) {
|
|
||||||
logger.debug("[AuthHandler] Set accessToken: " + accessToken);
|
|
||||||
logger.debug("[AuthHandler] Set UUID: " + uuid);
|
|
||||||
logger.debug("[AuthHandler] For this username: " + username);
|
|
||||||
}
|
|
||||||
return goodResponse.equals(response);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean updateServerID(UUID uuid, String serverID) throws IOException {
|
|
||||||
String response = IOHelper.request(new URL(CommonHelper.replace(updateAuth, "serverid", IOHelper.urlEncode(serverID), "uuid", IOHelper.urlEncode(uuid.toString()))));
|
|
||||||
if (logger.isDebugEnabled()) {
|
|
||||||
logger.debug("[AuthHandler] Set serverID: " + serverID);
|
|
||||||
logger.debug("[AuthHandler] For this UUID: " + uuid);
|
|
||||||
}
|
|
||||||
return goodResponse.equals(response);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -141,8 +141,10 @@ public boolean onJoinServer(String serverID, String username, Client client) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(LaunchServer server) {
|
public void init(LaunchServer server) {
|
||||||
if (provider != null)
|
if (provider != null) {
|
||||||
provider.init(server);
|
provider.init(server);
|
||||||
|
logger.warn("HWIDProvider deprecated. Please use 'AuthSupportHardware' in AuthCoreProvider");
|
||||||
|
}
|
||||||
this.server = server;
|
this.server = server;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,17 @@
|
||||||
package pro.gravit.launchserver.auth.protect;
|
package pro.gravit.launchserver.auth.protect;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
import pro.gravit.launcher.profiles.ClientProfile;
|
import pro.gravit.launcher.profiles.ClientProfile;
|
||||||
|
import pro.gravit.launchserver.LaunchServer;
|
||||||
import pro.gravit.launchserver.auth.protect.interfaces.ProfilesProtectHandler;
|
import pro.gravit.launchserver.auth.protect.interfaces.ProfilesProtectHandler;
|
||||||
import pro.gravit.launchserver.socket.Client;
|
import pro.gravit.launchserver.socket.Client;
|
||||||
import pro.gravit.launchserver.socket.response.auth.AuthResponse;
|
import pro.gravit.launchserver.socket.response.auth.AuthResponse;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class StdProtectHandler extends ProtectHandler implements ProfilesProtectHandler {
|
public class StdProtectHandler extends ProtectHandler implements ProfilesProtectHandler {
|
||||||
|
private transient final Logger logger = LogManager.getLogger();
|
||||||
public Map<String, List<String>> profileWhitelist = new HashMap<>();
|
public Map<String, List<String>> profileWhitelist = new HashMap<>();
|
||||||
public List<String> allowUpdates = new ArrayList<>();
|
public List<String> allowUpdates = new ArrayList<>();
|
||||||
|
|
||||||
|
@ -24,14 +25,21 @@ public void checkLaunchServerLicense() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(LaunchServer server) {
|
||||||
|
if(profileWhitelist != null && profileWhitelist.size() > 0) {
|
||||||
|
logger.warn("profileWhitelist deprecated. Please use permission 'launchserver.profile.PROFILE_UUID.show' and 'launchserver.profile.PROFILE_UUID.enter'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canGetProfile(ClientProfile profile, Client client) {
|
public boolean canGetProfile(ClientProfile profile, Client client) {
|
||||||
return canChangeProfile(profile, client);
|
return !profile.isLimited() || isWhitelisted("launchserver.profile.%s.show", profile, client);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canChangeProfile(ClientProfile profile, Client client) {
|
public boolean canChangeProfile(ClientProfile profile, Client client) {
|
||||||
return client.isAuth && client.username != null && isWhitelisted(profile.getTitle(), client.username);
|
return !profile.isLimited() || isWhitelisted("launchserver.profile.%s.enter", profile, client);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -39,9 +47,19 @@ public boolean canGetUpdates(String updatesDirName, Client client) {
|
||||||
return client.profile != null && (client.profile.getDir().equals(updatesDirName) || client.profile.getAssetDir().equals(updatesDirName) || allowUpdates.contains(updatesDirName));
|
return client.profile != null && (client.profile.getDir().equals(updatesDirName) || client.profile.getAssetDir().equals(updatesDirName) || allowUpdates.contains(updatesDirName));
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isWhitelisted(String profileTitle, String username) {
|
private boolean isWhitelisted(String property, ClientProfile profile, Client client) {
|
||||||
List<String> allowedUsername = profileWhitelist.get(profileTitle);
|
if(client.permissions != null) {
|
||||||
if (allowedUsername == null) return true;
|
String permByUUID = String.format(property, profile.getUUID());
|
||||||
return allowedUsername.contains(username);
|
if(client.permissions.hasPerm(permByUUID)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
String permByTitle = String.format(property, profile.getTitle().toLowerCase(Locale.ROOT));
|
||||||
|
if(client.permissions.hasPerm(permByTitle)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
List<String> allowedUsername = profileWhitelist.get(profile.getTitle());
|
||||||
|
if (allowedUsername != null && allowedUsername.contains(client.username)) return true;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
package pro.gravit.launchserver.auth.provider;
|
|
||||||
|
|
||||||
import pro.gravit.launcher.ClientPermissions;
|
|
||||||
import pro.gravit.launcher.request.auth.AuthRequest;
|
|
||||||
import pro.gravit.utils.helper.SecurityHelper;
|
|
||||||
|
|
||||||
public final class AcceptAuthProvider extends AuthProvider {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AuthProviderResult auth(String login, AuthRequest.AuthPasswordInterface password, String ip) {
|
|
||||||
return new AuthProviderResult(login, SecurityHelper.randomStringToken(), ClientPermissions.DEFAULT); // Same as login
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
// Do nothing
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,73 +0,0 @@
|
||||||
package pro.gravit.launchserver.auth.provider;
|
|
||||||
|
|
||||||
import pro.gravit.launcher.events.request.GetAvailabilityAuthRequestEvent;
|
|
||||||
import pro.gravit.launcher.request.auth.AuthRequest;
|
|
||||||
import pro.gravit.launcher.request.auth.details.AuthPasswordDetails;
|
|
||||||
import pro.gravit.launchserver.LaunchServer;
|
|
||||||
import pro.gravit.launchserver.auth.AuthException;
|
|
||||||
import pro.gravit.launchserver.socket.Client;
|
|
||||||
import pro.gravit.utils.ProviderMap;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public abstract class AuthProvider implements AutoCloseable {
|
|
||||||
public static final ProviderMap<AuthProvider> providers = new ProviderMap<>("AuthProvider");
|
|
||||||
private static boolean registredProv = false;
|
|
||||||
protected transient LaunchServer srv = null;
|
|
||||||
|
|
||||||
public static AuthProviderResult authError(String message) throws AuthException {
|
|
||||||
throw new AuthException(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public static void registerProviders() {
|
|
||||||
if (!registredProv) {
|
|
||||||
providers.register("null", NullAuthProvider.class);
|
|
||||||
providers.register("accept", AcceptAuthProvider.class);
|
|
||||||
providers.register("reject", RejectAuthProvider.class);
|
|
||||||
providers.register("mysql", MySQLAuthProvider.class);
|
|
||||||
providers.register("postgresql", PostgreSQLAuthProvider.class);
|
|
||||||
providers.register("request", RequestAuthProvider.class);
|
|
||||||
providers.register("json", JsonAuthProvider.class);
|
|
||||||
providers.register("hibernate", HibernateAuthProvider.class);
|
|
||||||
registredProv = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public GetAvailabilityAuthRequestEvent.AuthAvailability.AuthType getFirstAuthType() {
|
|
||||||
return GetAvailabilityAuthRequestEvent.AuthAvailability.AuthType.PASSWORD;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public GetAvailabilityAuthRequestEvent.AuthAvailability.AuthType getSecondAuthType() {
|
|
||||||
return GetAvailabilityAuthRequestEvent.AuthAvailability.AuthType.NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<GetAvailabilityAuthRequestEvent.AuthAvailabilityDetails> getDetails(Client client) {
|
|
||||||
return List.of(new AuthPasswordDetails());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Verifies the username and password
|
|
||||||
*
|
|
||||||
* @param login user login
|
|
||||||
* @param password user password
|
|
||||||
* @param ip user ip
|
|
||||||
* @return player privileges, effective username and authorization token
|
|
||||||
* @throws Exception Throws an exception {@link AuthException} {@link pro.gravit.utils.HookException} if the verification script returned a meaningful error
|
|
||||||
* In other cases, throwing an exception indicates a serious error
|
|
||||||
*/
|
|
||||||
public abstract AuthProviderResult auth(String login, AuthRequest.AuthPasswordInterface password, String ip) throws Exception;
|
|
||||||
|
|
||||||
public void preAuth(String login, AuthRequest.AuthPasswordInterface password, String ip) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public abstract void close() throws IOException;
|
|
||||||
|
|
||||||
public void init(LaunchServer srv) {
|
|
||||||
this.srv = srv;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
package pro.gravit.launchserver.auth.provider;
|
|
||||||
|
|
||||||
import pro.gravit.launcher.ClientPermissions;
|
|
||||||
import pro.gravit.launchserver.dao.User;
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public class AuthProviderDAOResult extends AuthProviderResult {
|
|
||||||
public User daoObject;
|
|
||||||
|
|
||||||
public AuthProviderDAOResult(String username, String accessToken) {
|
|
||||||
super(username, accessToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
public AuthProviderDAOResult(String username, String accessToken, ClientPermissions permissions) {
|
|
||||||
super(username, accessToken, permissions);
|
|
||||||
}
|
|
||||||
|
|
||||||
public AuthProviderDAOResult(String username, String accessToken, ClientPermissions permissions, User daoObject) {
|
|
||||||
super(username, accessToken, permissions);
|
|
||||||
this.daoObject = daoObject;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
package pro.gravit.launchserver.auth.provider;
|
|
||||||
|
|
||||||
import pro.gravit.launcher.ClientPermissions;
|
|
||||||
|
|
||||||
|
|
||||||
public class AuthProviderResult {
|
|
||||||
public final String username;
|
|
||||||
public final String accessToken;
|
|
||||||
public final ClientPermissions permissions;
|
|
||||||
|
|
||||||
public AuthProviderResult(String username, String accessToken) {
|
|
||||||
this.username = username;
|
|
||||||
this.accessToken = accessToken;
|
|
||||||
permissions = ClientPermissions.DEFAULT;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AuthProviderResult(String username, String accessToken, ClientPermissions permissions) {
|
|
||||||
this.username = username;
|
|
||||||
this.accessToken = accessToken;
|
|
||||||
this.permissions = permissions;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
package pro.gravit.launchserver.auth.provider;
|
|
||||||
|
|
||||||
import pro.gravit.launchserver.auth.AuthException;
|
|
||||||
import pro.gravit.utils.helper.SecurityHelper;
|
|
||||||
import pro.gravit.utils.helper.SecurityHelper.DigestAlgorithm;
|
|
||||||
|
|
||||||
public abstract class DigestAuthProvider extends AuthProvider {
|
|
||||||
private DigestAlgorithm digest;
|
|
||||||
|
|
||||||
|
|
||||||
protected final void verifyDigest(String validDigest, String password) throws AuthException {
|
|
||||||
boolean valid;
|
|
||||||
if (digest == DigestAlgorithm.PLAIN)
|
|
||||||
valid = password.equals(validDigest);
|
|
||||||
else if (validDigest == null)
|
|
||||||
valid = false;
|
|
||||||
else {
|
|
||||||
byte[] actualDigest = SecurityHelper.digest(digest, password);
|
|
||||||
valid = SecurityHelper.toHex(actualDigest).equals(validDigest);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify is valid
|
|
||||||
if (!valid)
|
|
||||||
authError("Incorrect username or password");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,38 +0,0 @@
|
||||||
package pro.gravit.launchserver.auth.provider;
|
|
||||||
|
|
||||||
import pro.gravit.launcher.request.auth.AuthRequest;
|
|
||||||
import pro.gravit.launcher.request.auth.password.AuthPlainPassword;
|
|
||||||
import pro.gravit.launchserver.auth.AuthException;
|
|
||||||
import pro.gravit.launchserver.auth.RequiredDAO;
|
|
||||||
import pro.gravit.launchserver.dao.User;
|
|
||||||
import pro.gravit.launchserver.manangers.hook.AuthHookManager;
|
|
||||||
import pro.gravit.utils.helper.SecurityHelper;
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public class HibernateAuthProvider extends AuthProvider implements RequiredDAO {
|
|
||||||
public boolean autoReg;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AuthProviderResult auth(String login, AuthRequest.AuthPasswordInterface password, String ip) throws Exception {
|
|
||||||
if (!(password instanceof AuthPlainPassword)) throw new AuthException("This password type not supported");
|
|
||||||
User user = srv.config.dao.userDAO.findByUsername(login);
|
|
||||||
if (user == null && autoReg) {
|
|
||||||
AuthHookManager.RegContext context = new AuthHookManager.RegContext(login, ((AuthPlainPassword) password).password, ip, false);
|
|
||||||
if (srv.authHookManager.registraion.hook(context)) {
|
|
||||||
//user = srv.config.dao.userService.registerNewUser(login, ((AuthPlainPassword) password).password); //TODO: FIX
|
|
||||||
} else {
|
|
||||||
throw new AuthException("Registration canceled. Try again later");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (user == null || !user.verifyPassword(((AuthPlainPassword) password).password)) {
|
|
||||||
if (user == null) throw new AuthException("Username incorrect");
|
|
||||||
else throw new AuthException("Username or password incorrect");
|
|
||||||
}
|
|
||||||
return new AuthProviderDAOResult(user.getUsername(), SecurityHelper.randomStringToken(), user.getPermissions(), user);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,90 +0,0 @@
|
||||||
package pro.gravit.launchserver.auth.provider;
|
|
||||||
|
|
||||||
import com.google.gson.JsonElement;
|
|
||||||
import pro.gravit.launcher.ClientPermissions;
|
|
||||||
import pro.gravit.launcher.HTTPRequest;
|
|
||||||
import pro.gravit.launcher.Launcher;
|
|
||||||
import pro.gravit.launcher.request.auth.AuthRequest;
|
|
||||||
import pro.gravit.launcher.request.auth.password.Auth2FAPassword;
|
|
||||||
import pro.gravit.launcher.request.auth.password.AuthPlainPassword;
|
|
||||||
import pro.gravit.launcher.request.auth.password.AuthTOTPPassword;
|
|
||||||
import pro.gravit.launchserver.auth.AuthException;
|
|
||||||
import pro.gravit.utils.helper.SecurityHelper;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
public final class JsonAuthProvider extends AuthProvider {
|
|
||||||
public URL url;
|
|
||||||
public boolean enable2FA;
|
|
||||||
public String apiKey;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AuthProviderResult auth(String login, AuthRequest.AuthPasswordInterface password, String ip) throws IOException {
|
|
||||||
String firstPassword;
|
|
||||||
String secondPassword;
|
|
||||||
if (!enable2FA) {
|
|
||||||
if (!(password instanceof AuthPlainPassword)) throw new AuthException("This password type not supported");
|
|
||||||
firstPassword = ((AuthPlainPassword) password).password;
|
|
||||||
secondPassword = null;
|
|
||||||
} else {
|
|
||||||
if (password instanceof AuthPlainPassword) {
|
|
||||||
firstPassword = ((AuthPlainPassword) password).password;
|
|
||||||
secondPassword = null;
|
|
||||||
} else if (password instanceof Auth2FAPassword) {
|
|
||||||
if (!(((Auth2FAPassword) password).firstPassword instanceof AuthPlainPassword))
|
|
||||||
throw new AuthException("This password type not supported");
|
|
||||||
firstPassword = ((AuthPlainPassword) ((Auth2FAPassword) password).firstPassword).password;
|
|
||||||
if (!(((Auth2FAPassword) password).secondPassword instanceof AuthTOTPPassword))
|
|
||||||
throw new AuthException("This password type not supported");
|
|
||||||
secondPassword = ((AuthTOTPPassword) ((Auth2FAPassword) password).secondPassword).totp;
|
|
||||||
} else {
|
|
||||||
throw new AuthException("This password type not supported");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
JsonElement content = HTTPRequest.jsonRequest(Launcher.gsonManager.gson.toJsonTree(new authRequest(login, firstPassword, secondPassword, ip, apiKey)), url);
|
|
||||||
if (!content.isJsonObject())
|
|
||||||
return authError("Authentication server response is malformed");
|
|
||||||
authResult result = Launcher.gsonManager.gson.fromJson(content, authResult.class);
|
|
||||||
if (result.username != null)
|
|
||||||
return new AuthProviderResult(result.username, SecurityHelper.randomStringToken(), new ClientPermissions(result.permissions, result.flags));
|
|
||||||
else return authError(Objects.requireNonNullElse(result.error, "Authentication server response is malformed"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
// pass
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class authResult {
|
|
||||||
String username;
|
|
||||||
String error;
|
|
||||||
long permissions;
|
|
||||||
long flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class authRequest {
|
|
||||||
final String username;
|
|
||||||
final String password;
|
|
||||||
final String secondPassword;
|
|
||||||
final String ip;
|
|
||||||
String apiKey;
|
|
||||||
|
|
||||||
public authRequest(String username, String password, String ip) {
|
|
||||||
this.username = username;
|
|
||||||
this.password = password;
|
|
||||||
this.secondPassword = null;
|
|
||||||
this.ip = ip;
|
|
||||||
}
|
|
||||||
|
|
||||||
public authRequest(String username, String password, String secondPassword, String ip, String apiKey) {
|
|
||||||
this.username = username;
|
|
||||||
this.password = password;
|
|
||||||
this.secondPassword = secondPassword;
|
|
||||||
this.ip = ip;
|
|
||||||
this.apiKey = apiKey;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,56 +0,0 @@
|
||||||
package pro.gravit.launchserver.auth.provider;
|
|
||||||
|
|
||||||
import pro.gravit.launcher.ClientPermissions;
|
|
||||||
import pro.gravit.launcher.request.auth.AuthRequest;
|
|
||||||
import pro.gravit.launcher.request.auth.password.AuthPlainPassword;
|
|
||||||
import pro.gravit.launchserver.LaunchServer;
|
|
||||||
import pro.gravit.launchserver.auth.AuthException;
|
|
||||||
import pro.gravit.launchserver.auth.MySQLSourceConfig;
|
|
||||||
import pro.gravit.utils.helper.CommonHelper;
|
|
||||||
import pro.gravit.utils.helper.SecurityHelper;
|
|
||||||
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.PreparedStatement;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
|
|
||||||
public final class MySQLAuthProvider extends AuthProvider {
|
|
||||||
private MySQLSourceConfig mySQLHolder;
|
|
||||||
private String query;
|
|
||||||
private String message;
|
|
||||||
private String[] queryParams;
|
|
||||||
private boolean flagsEnabled;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init(LaunchServer srv) {
|
|
||||||
super.init(srv);
|
|
||||||
if (mySQLHolder == null) throw new RuntimeException("[Verify][AuthProvider] mySQLHolder cannot be null");
|
|
||||||
if (query == null) throw new RuntimeException("[Verify][AuthProvider] query cannot be null");
|
|
||||||
if (message == null) throw new RuntimeException("[Verify][AuthProvider] message cannot be null");
|
|
||||||
if (queryParams == null) throw new RuntimeException("[Verify][AuthProvider] queryParams cannot be null");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AuthProviderResult auth(String login, AuthRequest.AuthPasswordInterface password, String ip) throws SQLException, AuthException {
|
|
||||||
if (!(password instanceof AuthPlainPassword)) throw new AuthException("This password type not supported");
|
|
||||||
try (Connection c = mySQLHolder.getConnection()) {
|
|
||||||
PreparedStatement s = c.prepareStatement(query);
|
|
||||||
String[] replaceParams = {"login", login, "password", ((AuthPlainPassword) password).password, "ip", ip};
|
|
||||||
for (int i = 0; i < queryParams.length; i++)
|
|
||||||
s.setString(i + 1, CommonHelper.replace(queryParams[i], replaceParams));
|
|
||||||
|
|
||||||
// Execute SQL query
|
|
||||||
s.setQueryTimeout(MySQLSourceConfig.TIMEOUT);
|
|
||||||
try (ResultSet set = s.executeQuery()) {
|
|
||||||
return set.next() ? new AuthProviderResult(set.getString(1), SecurityHelper.randomStringToken(), new ClientPermissions(
|
|
||||||
set.getLong(2), flagsEnabled ? set.getLong(3) : 0)) : authError(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
mySQLHolder.close();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,32 +0,0 @@
|
||||||
package pro.gravit.launchserver.auth.provider;
|
|
||||||
|
|
||||||
import pro.gravit.launcher.request.auth.AuthRequest;
|
|
||||||
import pro.gravit.utils.helper.VerifyHelper;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
public final class NullAuthProvider extends AuthProvider {
|
|
||||||
private volatile AuthProvider provider;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AuthProviderResult auth(String login, AuthRequest.AuthPasswordInterface password, String ip) throws Exception {
|
|
||||||
return getProvider().auth(login, password, ip);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() throws IOException {
|
|
||||||
AuthProvider provider = this.provider;
|
|
||||||
if (provider != null)
|
|
||||||
provider.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
private AuthProvider getProvider() {
|
|
||||||
return VerifyHelper.verify(provider, Objects::nonNull, "Backend auth provider wasn't set");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void setBackend(AuthProvider provider) {
|
|
||||||
this.provider = provider;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,46 +0,0 @@
|
||||||
package pro.gravit.launchserver.auth.provider;
|
|
||||||
|
|
||||||
|
|
||||||
import pro.gravit.launcher.ClientPermissions;
|
|
||||||
import pro.gravit.launcher.request.auth.AuthRequest;
|
|
||||||
import pro.gravit.launcher.request.auth.password.AuthPlainPassword;
|
|
||||||
import pro.gravit.launchserver.auth.AuthException;
|
|
||||||
import pro.gravit.launchserver.auth.PostgreSQLSourceConfig;
|
|
||||||
import pro.gravit.utils.helper.CommonHelper;
|
|
||||||
import pro.gravit.utils.helper.SecurityHelper;
|
|
||||||
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.PreparedStatement;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
|
|
||||||
public final class PostgreSQLAuthProvider extends AuthProvider {
|
|
||||||
private PostgreSQLSourceConfig postgreSQLHolder;
|
|
||||||
private String query;
|
|
||||||
private String message;
|
|
||||||
private String[] queryParams;
|
|
||||||
private boolean flagsEnabled;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AuthProviderResult auth(String login, AuthRequest.AuthPasswordInterface password, String ip) throws SQLException, AuthException {
|
|
||||||
if (!(password instanceof AuthPlainPassword)) throw new AuthException("This password type not supported");
|
|
||||||
try (Connection c = postgreSQLHolder.getConnection(); PreparedStatement s = c.prepareStatement(query)) {
|
|
||||||
String[] replaceParams = {"login", login, "password", ((AuthPlainPassword) password).password, "ip", ip};
|
|
||||||
for (int i = 0; i < queryParams.length; i++) {
|
|
||||||
s.setString(i + 1, CommonHelper.replace(queryParams[i], replaceParams));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Execute SQL query
|
|
||||||
s.setQueryTimeout(PostgreSQLSourceConfig.TIMEOUT);
|
|
||||||
try (ResultSet set = s.executeQuery()) {
|
|
||||||
return set.next() ? new AuthProviderResult(set.getString(1), SecurityHelper.randomStringToken(), new ClientPermissions(
|
|
||||||
set.getLong(2), flagsEnabled ? set.getLong(3) : 0)) : authError(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
postgreSQLHolder.close();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,67 +0,0 @@
|
||||||
package pro.gravit.launchserver.auth.provider;
|
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
import pro.gravit.launcher.ClientPermissions;
|
|
||||||
import pro.gravit.launcher.request.auth.AuthRequest;
|
|
||||||
import pro.gravit.launchserver.Reconfigurable;
|
|
||||||
import pro.gravit.launchserver.auth.AuthException;
|
|
||||||
import pro.gravit.utils.command.Command;
|
|
||||||
import pro.gravit.utils.command.SubCommand;
|
|
||||||
import pro.gravit.utils.helper.SecurityHelper;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public final class RejectAuthProvider extends AuthProvider implements Reconfigurable {
|
|
||||||
private transient final Logger logger = LogManager.getLogger();
|
|
||||||
public String message;
|
|
||||||
public ArrayList<String> whitelist = new ArrayList<>();
|
|
||||||
|
|
||||||
public RejectAuthProvider() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public RejectAuthProvider(String message) {
|
|
||||||
this.message = message;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AuthProviderResult auth(String login, AuthRequest.AuthPasswordInterface password, String ip) throws AuthException {
|
|
||||||
if (whitelist != null) {
|
|
||||||
for (String username : whitelist) {
|
|
||||||
if (login.equals(username)) {
|
|
||||||
return new AuthProviderResult(login, SecurityHelper.randomStringToken(), ClientPermissions.DEFAULT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return authError(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
// Do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, Command> getCommands() {
|
|
||||||
Map<String, Command> commands = new HashMap<>();
|
|
||||||
commands.put("message", new SubCommand() {
|
|
||||||
@Override
|
|
||||||
public void invoke(String... args) throws Exception {
|
|
||||||
verifyArgs(args, 1);
|
|
||||||
message = args[0];
|
|
||||||
logger.info("New reject message: {}", message);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
commands.put("whitelist.add", new SubCommand() {
|
|
||||||
@Override
|
|
||||||
public void invoke(String... args) throws Exception {
|
|
||||||
verifyArgs(args, 1);
|
|
||||||
whitelist.add(args[0]);
|
|
||||||
logger.info("{} added to whitelist", args[0]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return commands;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,68 +0,0 @@
|
||||||
package pro.gravit.launchserver.auth.provider;
|
|
||||||
|
|
||||||
import pro.gravit.launcher.ClientPermissions;
|
|
||||||
import pro.gravit.launcher.request.auth.AuthRequest;
|
|
||||||
import pro.gravit.launcher.request.auth.password.AuthPlainPassword;
|
|
||||||
import pro.gravit.launchserver.LaunchServer;
|
|
||||||
import pro.gravit.launchserver.auth.AuthException;
|
|
||||||
import pro.gravit.utils.helper.CommonHelper;
|
|
||||||
import pro.gravit.utils.helper.IOHelper;
|
|
||||||
import pro.gravit.utils.helper.SecurityHelper;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URI;
|
|
||||||
import java.net.URISyntaxException;
|
|
||||||
import java.net.http.HttpClient;
|
|
||||||
import java.net.http.HttpRequest;
|
|
||||||
import java.net.http.HttpResponse;
|
|
||||||
import java.time.Duration;
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
public final class RequestAuthProvider extends AuthProvider {
|
|
||||||
private transient final HttpClient client = HttpClient.newBuilder()
|
|
||||||
.build();
|
|
||||||
public String url;
|
|
||||||
public transient Pattern pattern;
|
|
||||||
public String response;
|
|
||||||
public boolean flagsEnabled;
|
|
||||||
public boolean usePermission = true;
|
|
||||||
public int timeout = 5000;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init(LaunchServer srv) {
|
|
||||||
super.init(srv);
|
|
||||||
if (url == null) throw new RuntimeException("[Verify][AuthProvider] url cannot be null");
|
|
||||||
if (response == null) throw new RuntimeException("[Verify][AuthProvider] response cannot be null");
|
|
||||||
pattern = Pattern.compile(response);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AuthProviderResult auth(String login, AuthRequest.AuthPasswordInterface password, String ip) throws IOException, URISyntaxException, InterruptedException {
|
|
||||||
if (!(password instanceof AuthPlainPassword)) throw new AuthException("This password type not supported");
|
|
||||||
HttpResponse<String> response = client.send(HttpRequest.newBuilder()
|
|
||||||
.uri(new URI(getFormattedURL(login, ((AuthPlainPassword) password).password, ip)))
|
|
||||||
.header("User-Agent", IOHelper.USER_AGENT)
|
|
||||||
.timeout(Duration.ofMillis(timeout))
|
|
||||||
.GET()
|
|
||||||
.build(), HttpResponse.BodyHandlers.ofString());
|
|
||||||
|
|
||||||
// Match username
|
|
||||||
String currentResponse = response.body();
|
|
||||||
Matcher matcher = pattern.matcher(currentResponse);
|
|
||||||
return matcher.matches() && matcher.groupCount() >= 1 ?
|
|
||||||
new AuthProviderResult(matcher.group("username"), SecurityHelper.randomStringToken(), new ClientPermissions(
|
|
||||||
usePermission ? Long.parseLong(matcher.group("permissions")) : 0, flagsEnabled ? Long.parseLong(matcher.group("flags")) : 0)) :
|
|
||||||
authError(currentResponse);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
// Do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getFormattedURL(String login, String password, String ip) {
|
|
||||||
return CommonHelper.replace(url, "login", IOHelper.urlEncode(login), "password", IOHelper.urlEncode(password), "ip", IOHelper.urlEncode(ip));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -30,7 +30,6 @@
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
import java.util.jar.JarFile;
|
import java.util.jar.JarFile;
|
||||||
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipEntry;
|
||||||
|
@ -98,36 +97,6 @@ public void pushBytes(String filename, byte[] bytes) throws IOException {
|
||||||
fileList.add(filename);
|
fileList.add(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public void pushJarFile(ZipInputStream input) throws IOException {
|
|
||||||
ZipEntry e = input.getNextEntry();
|
|
||||||
while (e != null) {
|
|
||||||
if (fileList.contains(e.getName())) {
|
|
||||||
e = input.getNextEntry();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
output.putNextEntry(IOHelper.newZipEntry(e));
|
|
||||||
IOHelper.transfer(input, output);
|
|
||||||
fileList.add(e.getName());
|
|
||||||
e = input.getNextEntry();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public void pushJarFile(ZipInputStream input, Set<String> blacklist) throws IOException {
|
|
||||||
ZipEntry e = input.getNextEntry();
|
|
||||||
while (e != null) {
|
|
||||||
if (fileList.contains(e.getName()) || blacklist.contains(e.getName())) {
|
|
||||||
e = input.getNextEntry();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
output.putNextEntry(IOHelper.newZipEntry(e));
|
|
||||||
IOHelper.transfer(input, output);
|
|
||||||
fileList.add(e.getName());
|
|
||||||
e = input.getNextEntry();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void pushJarFile(Path jarfile, Predicate<ZipEntry> filter, Predicate<String> needTransform) throws IOException {
|
public void pushJarFile(Path jarfile, Predicate<ZipEntry> filter, Predicate<String> needTransform) throws IOException {
|
||||||
pushJarFile(jarfile.toUri().toURL(), filter, needTransform);
|
pushJarFile(jarfile.toUri().toURL(), filter, needTransform);
|
||||||
}
|
}
|
||||||
|
|
|
@ -134,8 +134,7 @@ public byte[] transformClass(byte[] bytes, String classname, BuildContext contex
|
||||||
ClassWriter writer;
|
ClassWriter writer;
|
||||||
ClassNode cn = null;
|
ClassNode cn = null;
|
||||||
for (Transformer t : transformers) {
|
for (Transformer t : transformers) {
|
||||||
if (t instanceof ASMTransformer) {
|
if (t instanceof ASMTransformer asmTransformer) {
|
||||||
ASMTransformer asmTransformer = (ASMTransformer) t;
|
|
||||||
if (cn == null) {
|
if (cn == null) {
|
||||||
ClassReader cr = new ClassReader(result);
|
ClassReader cr = new ClassReader(result);
|
||||||
cn = new ClassNode();
|
cn = new ClassNode();
|
||||||
|
|
|
@ -1,51 +0,0 @@
|
||||||
package pro.gravit.launchserver.command.auth;
|
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
import pro.gravit.launcher.request.auth.password.AuthPlainPassword;
|
|
||||||
import pro.gravit.launchserver.LaunchServer;
|
|
||||||
import pro.gravit.launchserver.auth.AuthProviderPair;
|
|
||||||
import pro.gravit.launchserver.auth.provider.AuthProvider;
|
|
||||||
import pro.gravit.launchserver.auth.provider.AuthProviderResult;
|
|
||||||
import pro.gravit.launchserver.command.Command;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public final class AuthCommand extends Command {
|
|
||||||
private transient final Logger logger = LogManager.getLogger();
|
|
||||||
|
|
||||||
public AuthCommand(LaunchServer server) {
|
|
||||||
super(server);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getArgsDescription() {
|
|
||||||
return "<login> <password> <auth_id>";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getUsageDescription() {
|
|
||||||
return "Try to auth with specified login and password";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void invoke(String... args) throws Exception {
|
|
||||||
verifyArgs(args, 2);
|
|
||||||
AuthProviderPair pair;
|
|
||||||
if (args.length > 2) pair = server.config.getAuthProviderPair(args[2]);
|
|
||||||
else pair = server.config.getAuthProviderPair();
|
|
||||||
if (pair == null) throw new IllegalStateException(String.format("Auth %s not found", args[1]));
|
|
||||||
if (pair.isUseCore())
|
|
||||||
throw new UnsupportedOperationException(String.format("Please use `config auth.%s.core COMMAND ARGS`", pair.name));
|
|
||||||
String login = args[0];
|
|
||||||
String password = args[1];
|
|
||||||
|
|
||||||
// Authenticate
|
|
||||||
AuthProvider provider = pair.provider;
|
|
||||||
AuthProviderResult result = provider.auth(login, new AuthPlainPassword(password), "127.0.0.1");
|
|
||||||
UUID uuid = pair.handler.auth(result);
|
|
||||||
|
|
||||||
// Print auth successful message
|
|
||||||
logger.info("UUID: {}, Username: '{}', Access Token: '{}'", uuid, result.username, result.accessToken);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,49 +0,0 @@
|
||||||
package pro.gravit.launchserver.command.auth;
|
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
import pro.gravit.launchserver.LaunchServer;
|
|
||||||
import pro.gravit.launchserver.auth.AuthProviderPair;
|
|
||||||
import pro.gravit.launchserver.command.Command;
|
|
||||||
import pro.gravit.utils.command.CommandException;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public final class UUIDToUsernameCommand extends Command {
|
|
||||||
private transient final Logger logger = LogManager.getLogger();
|
|
||||||
|
|
||||||
public UUIDToUsernameCommand(LaunchServer server) {
|
|
||||||
super(server);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getArgsDescription() {
|
|
||||||
return "<uuid> <auth_id>";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getUsageDescription() {
|
|
||||||
return "Convert player UUID to username";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void invoke(String... args) throws CommandException, IOException {
|
|
||||||
verifyArgs(args, 1);
|
|
||||||
AuthProviderPair pair;
|
|
||||||
if (args.length > 1) pair = server.config.getAuthProviderPair(args[1]);
|
|
||||||
else pair = server.config.getAuthProviderPair();
|
|
||||||
if (pair == null) throw new IllegalStateException(String.format("Auth %s not found", args[1]));
|
|
||||||
if (pair.isUseCore())
|
|
||||||
throw new UnsupportedOperationException(String.format("Please use `config auth.%s.core COMMAND ARGS`", pair.name));
|
|
||||||
UUID uuid = parseUUID(args[0]);
|
|
||||||
|
|
||||||
// Get UUID by username
|
|
||||||
String username = pair.handler.uuidToUsername(uuid);
|
|
||||||
if (username == null)
|
|
||||||
throw new CommandException("Unknown UUID: " + uuid);
|
|
||||||
|
|
||||||
// Print username
|
|
||||||
logger.info("Username of player {}: '{}'", uuid, username);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,49 +0,0 @@
|
||||||
package pro.gravit.launchserver.command.auth;
|
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
import pro.gravit.launchserver.LaunchServer;
|
|
||||||
import pro.gravit.launchserver.auth.AuthProviderPair;
|
|
||||||
import pro.gravit.launchserver.command.Command;
|
|
||||||
import pro.gravit.utils.command.CommandException;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public final class UsernameToUUIDCommand extends Command {
|
|
||||||
private transient final Logger logger = LogManager.getLogger();
|
|
||||||
|
|
||||||
public UsernameToUUIDCommand(LaunchServer server) {
|
|
||||||
super(server);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getArgsDescription() {
|
|
||||||
return "<username> <auth_id>";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getUsageDescription() {
|
|
||||||
return "Convert player username to UUID";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void invoke(String... args) throws CommandException, IOException {
|
|
||||||
verifyArgs(args, 1);
|
|
||||||
AuthProviderPair pair;
|
|
||||||
if (args.length > 1) pair = server.config.getAuthProviderPair(args[1]);
|
|
||||||
else pair = server.config.getAuthProviderPair();
|
|
||||||
if (pair == null) throw new IllegalStateException(String.format("Auth %s not found", args[1]));
|
|
||||||
if (pair.isUseCore())
|
|
||||||
throw new UnsupportedOperationException(String.format("Please use `config auth.%s.core COMMAND ARGS`", pair.name));
|
|
||||||
String username = parseUsername(args[0]);
|
|
||||||
|
|
||||||
// Get UUID by username
|
|
||||||
UUID uuid = pair.handler.usernameToUUID(username);
|
|
||||||
if (uuid == null)
|
|
||||||
throw new CommandException(String.format("Unknown username: '%s'", username));
|
|
||||||
|
|
||||||
// Print UUID
|
|
||||||
logger.info("UUID of player '{}': {}", username, uuid);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,9 +1,6 @@
|
||||||
package pro.gravit.launchserver.command.handler;
|
package pro.gravit.launchserver.command.handler;
|
||||||
|
|
||||||
import pro.gravit.launchserver.LaunchServer;
|
import pro.gravit.launchserver.LaunchServer;
|
||||||
import pro.gravit.launchserver.command.auth.AuthCommand;
|
|
||||||
import pro.gravit.launchserver.command.auth.UUIDToUsernameCommand;
|
|
||||||
import pro.gravit.launchserver.command.auth.UsernameToUUIDCommand;
|
|
||||||
import pro.gravit.launchserver.command.basic.BuildCommand;
|
import pro.gravit.launchserver.command.basic.BuildCommand;
|
||||||
import pro.gravit.launchserver.command.basic.RestartCommand;
|
import pro.gravit.launchserver.command.basic.RestartCommand;
|
||||||
import pro.gravit.launchserver.command.basic.StopCommand;
|
import pro.gravit.launchserver.command.basic.StopCommand;
|
||||||
|
@ -50,14 +47,6 @@ public static void registerCommands(pro.gravit.utils.command.CommandHandler hand
|
||||||
Category updatesCategory = new Category(updates, "updates", "Update and Sync Management");
|
Category updatesCategory = new Category(updates, "updates", "Update and Sync Management");
|
||||||
handler.registerCategory(updatesCategory);
|
handler.registerCategory(updatesCategory);
|
||||||
|
|
||||||
// Register auth commands
|
|
||||||
BaseCommandCategory auth = new BaseCommandCategory();
|
|
||||||
auth.registerCommand("auth", new AuthCommand(server));
|
|
||||||
auth.registerCommand("usernameToUUID", new UsernameToUUIDCommand(server));
|
|
||||||
auth.registerCommand("uuidToUsername", new UUIDToUsernameCommand(server));
|
|
||||||
Category authCategory = new Category(auth, "auth", "User Management");
|
|
||||||
handler.registerCategory(authCategory);
|
|
||||||
|
|
||||||
//Register service commands
|
//Register service commands
|
||||||
BaseCommandCategory service = new BaseCommandCategory();
|
BaseCommandCategory service = new BaseCommandCategory();
|
||||||
service.registerCommand("config", new ConfigCommand(server));
|
service.registerCommand("config", new ConfigCommand(server));
|
||||||
|
@ -69,6 +58,7 @@ public static void registerCommands(pro.gravit.utils.command.CommandHandler hand
|
||||||
service.registerCommand("signDir", new SignDirCommand(server));
|
service.registerCommand("signDir", new SignDirCommand(server));
|
||||||
service.registerCommand("pingServers", new PingServersCommand(server));
|
service.registerCommand("pingServers", new PingServersCommand(server));
|
||||||
service.registerCommand("securitycheck", new SecurityCheckCommand(server));
|
service.registerCommand("securitycheck", new SecurityCheckCommand(server));
|
||||||
|
service.registerCommand("token", new TokenCommand(server));
|
||||||
Category serviceCategory = new Category(service, "service", "Managing LaunchServer Components");
|
Category serviceCategory = new Category(service, "service", "Managing LaunchServer Components");
|
||||||
handler.registerCategory(serviceCategory);
|
handler.registerCategory(serviceCategory);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,6 @@
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import pro.gravit.launcher.Launcher;
|
import pro.gravit.launcher.Launcher;
|
||||||
import pro.gravit.launcher.profiles.ClientProfile;
|
import pro.gravit.launcher.profiles.ClientProfile;
|
||||||
import pro.gravit.launcher.profiles.optional.OptionalFile;
|
|
||||||
import pro.gravit.launcher.profiles.optional.OptionalTrigger;
|
|
||||||
import pro.gravit.launcher.profiles.optional.actions.*;
|
|
||||||
import pro.gravit.launchserver.LaunchServer;
|
import pro.gravit.launchserver.LaunchServer;
|
||||||
import pro.gravit.launchserver.command.Command;
|
import pro.gravit.launchserver.command.Command;
|
||||||
import pro.gravit.utils.helper.IOHelper;
|
import pro.gravit.utils.helper.IOHelper;
|
||||||
|
@ -16,9 +13,6 @@
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public class SaveProfilesCommand extends Command {
|
public class SaveProfilesCommand extends Command {
|
||||||
|
@ -28,7 +22,6 @@ public SaveProfilesCommand(LaunchServer server) {
|
||||||
super(server);
|
super(server);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public static void saveProfile(ClientProfile profile, Path path) throws IOException {
|
public static void saveProfile(ClientProfile profile, Path path) throws IOException {
|
||||||
if (profile.getUUID() == null) profile.setUUID(UUID.randomUUID());
|
if (profile.getUUID() == null) profile.setUUID(UUID.randomUUID());
|
||||||
if (profile.getServers().size() == 0) {
|
if (profile.getServers().size() == 0) {
|
||||||
|
@ -39,41 +32,6 @@ public static void saveProfile(ClientProfile profile, Path path) throws IOExcept
|
||||||
serverProfile.serverPort = profile.getServerPort();
|
serverProfile.serverPort = profile.getServerPort();
|
||||||
profile.getServers().add(serverProfile);
|
profile.getServers().add(serverProfile);
|
||||||
}
|
}
|
||||||
for (OptionalFile file : profile.getOptional()) {
|
|
||||||
if (file.list != null) {
|
|
||||||
String[] list = file.list;
|
|
||||||
file.list = null;
|
|
||||||
if (file.actions == null) file.actions = new ArrayList<>(2);
|
|
||||||
OptionalAction action;
|
|
||||||
switch (file.type) {
|
|
||||||
case FILE:
|
|
||||||
OptionalActionFile result = new OptionalActionFile(new HashMap<>());
|
|
||||||
for (String s : list) result.files.put(s, "");
|
|
||||||
action = result;
|
|
||||||
break;
|
|
||||||
case CLASSPATH:
|
|
||||||
action = new OptionalActionClassPath(list);
|
|
||||||
break;
|
|
||||||
case JVMARGS:
|
|
||||||
action = new OptionalActionJvmArgs(Arrays.asList(list));
|
|
||||||
break;
|
|
||||||
case CLIENTARGS:
|
|
||||||
action = new OptionalActionClientArgs(Arrays.asList(list));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
file.actions.add(action);
|
|
||||||
}
|
|
||||||
if (file.triggers != null) {
|
|
||||||
file.triggersList = new ArrayList<>(file.triggers.length);
|
|
||||||
for (OptionalTrigger trigger : file.triggers) {
|
|
||||||
pro.gravit.launcher.profiles.optional.triggers.OptionalTrigger newTrigger = trigger.toTrigger();
|
|
||||||
if (newTrigger != null) file.triggersList.add(newTrigger);
|
|
||||||
}
|
|
||||||
file.triggers = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try (Writer w = IOHelper.newWriter(path)) {
|
try (Writer w = IOHelper.newWriter(path)) {
|
||||||
Launcher.gsonManager.configGson.toJson(profile, w);
|
Launcher.gsonManager.configGson.toJson(profile, w);
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,10 +47,12 @@ public void invoke(String... args) {
|
||||||
logger.info("OAuth {} | session {}", client.useOAuth, client.sessionObject == null ? "null" : client.sessionObject);
|
logger.info("OAuth {} | session {}", client.useOAuth, client.sessionObject == null ? "null" : client.sessionObject);
|
||||||
logger.info("Data: checkSign {} | auth_id {}", client.checkSign ? "true" : "false",
|
logger.info("Data: checkSign {} | auth_id {}", client.checkSign ? "true" : "false",
|
||||||
client.auth_id);
|
client.auth_id);
|
||||||
|
}
|
||||||
if (client.trustLevel != null) {
|
if (client.trustLevel != null) {
|
||||||
logger.info("trustLevel | key {} | pubkey {}", client.trustLevel.keyChecked ? "checked" : "unchecked", client.trustLevel.publicKey == null ? "null" : new String(Base64.getEncoder().encode(client.trustLevel.publicKey)));
|
logger.info("trustLevel | key {} | pubkey {}", client.trustLevel.keyChecked ? "checked" : "unchecked", client.trustLevel.publicKey == null ? "null" : new String(Base64.getEncoder().encode(client.trustLevel.publicKey)));
|
||||||
}
|
}
|
||||||
logger.info("Permissions: {} (permissions {} | flags {})", client.permissions == null ? "null" : client.permissions.toString(), client.permissions == null ? 0 : client.permissions.permissions, client.permissions == null ? 0 : client.permissions.flags);
|
if (client.permissions != null) {
|
||||||
|
logger.info("Permissions: {}", client.permissions.toString());
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,18 +4,15 @@
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import pro.gravit.launcher.profiles.ClientProfile;
|
import pro.gravit.launcher.profiles.ClientProfile;
|
||||||
import pro.gravit.launchserver.LaunchServer;
|
import pro.gravit.launchserver.LaunchServer;
|
||||||
import pro.gravit.launchserver.auth.handler.MemoryAuthHandler;
|
|
||||||
import pro.gravit.launchserver.auth.protect.AdvancedProtectHandler;
|
import pro.gravit.launchserver.auth.protect.AdvancedProtectHandler;
|
||||||
import pro.gravit.launchserver.auth.protect.NoProtectHandler;
|
import pro.gravit.launchserver.auth.protect.NoProtectHandler;
|
||||||
import pro.gravit.launchserver.auth.protect.StdProtectHandler;
|
import pro.gravit.launchserver.auth.protect.StdProtectHandler;
|
||||||
import pro.gravit.launchserver.auth.provider.AcceptAuthProvider;
|
|
||||||
import pro.gravit.launchserver.command.Command;
|
import pro.gravit.launchserver.command.Command;
|
||||||
import pro.gravit.launchserver.components.ProGuardComponent;
|
import pro.gravit.launchserver.components.ProGuardComponent;
|
||||||
import pro.gravit.launchserver.config.LaunchServerConfig;
|
import pro.gravit.launchserver.config.LaunchServerConfig;
|
||||||
import pro.gravit.launchserver.helper.SignHelper;
|
import pro.gravit.launchserver.helper.SignHelper;
|
||||||
import pro.gravit.utils.helper.IOHelper;
|
import pro.gravit.utils.helper.IOHelper;
|
||||||
import pro.gravit.utils.helper.JVMHelper;
|
import pro.gravit.utils.helper.JVMHelper;
|
||||||
import pro.gravit.utils.helper.LogHelper;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -49,11 +46,6 @@ public static void printCheckResult(String module, String comment, Boolean statu
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public static void printCheckResult(LogHelper.Level level, String module, String comment, Boolean status) {
|
|
||||||
printCheckResult(module, comment, status);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getArgsDescription() {
|
public String getArgsDescription() {
|
||||||
return "[]";
|
return "[]";
|
||||||
|
@ -68,19 +60,6 @@ public String getUsageDescription() {
|
||||||
public void invoke(String... args) {
|
public void invoke(String... args) {
|
||||||
LaunchServerConfig config = server.config;
|
LaunchServerConfig config = server.config;
|
||||||
config.auth.forEach((name, pair) -> {
|
config.auth.forEach((name, pair) -> {
|
||||||
if (pair.provider instanceof AcceptAuthProvider) {
|
|
||||||
printCheckResult(String.format("auth.%s.provider", name), "Accept auth provider", false);
|
|
||||||
} else {
|
|
||||||
printCheckResult(String.format("auth.%s.provider", name), "", true);
|
|
||||||
}
|
|
||||||
if (pair.handler instanceof MemoryAuthHandler) {
|
|
||||||
printCheckResult(String.format("auth.%s.handler", name), "MemoryAuthHandler test-only", false);
|
|
||||||
} else {
|
|
||||||
printCheckResult(String.format("auth.%s.handler", name), "", true);
|
|
||||||
}
|
|
||||||
if (!pair.isUseCore()) {
|
|
||||||
printCheckResult(String.format("auth.%s", name), "AuthProvider/AuthHandler may be removed in future release", null);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
if (config.protectHandler instanceof NoProtectHandler) {
|
if (config.protectHandler instanceof NoProtectHandler) {
|
||||||
printCheckResult("protectHandler", "protectHandler none", false);
|
printCheckResult("protectHandler", "protectHandler none", false);
|
||||||
|
@ -171,19 +150,10 @@ public void invoke(String... args) {
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (config.env) {
|
switch (config.env) {
|
||||||
|
case DEV -> printCheckResult("env", "found env DEV", false);
|
||||||
case DEV:
|
case DEBUG -> printCheckResult("env", "found env DEBUG", false);
|
||||||
printCheckResult("env", "found env DEV", false);
|
case STD -> printCheckResult("env", "you can improve security by using env PROD", null);
|
||||||
break;
|
case PROD -> printCheckResult("env", "", true);
|
||||||
case DEBUG:
|
|
||||||
printCheckResult("env", "found env DEBUG", false);
|
|
||||||
break;
|
|
||||||
case STD:
|
|
||||||
printCheckResult("env", "you can improve security by using env PROD", null);
|
|
||||||
break;
|
|
||||||
case PROD:
|
|
||||||
printCheckResult("env", "", true);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Profiles
|
//Profiles
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import pro.gravit.launchserver.LaunchServer;
|
import pro.gravit.launchserver.LaunchServer;
|
||||||
import pro.gravit.launchserver.auth.AuthProviderPair;
|
import pro.gravit.launchserver.auth.AuthProviderPair;
|
||||||
import pro.gravit.launchserver.auth.handler.CachedAuthHandler;
|
|
||||||
import pro.gravit.launchserver.command.Command;
|
import pro.gravit.launchserver.command.Command;
|
||||||
import pro.gravit.utils.command.CommandHandler;
|
import pro.gravit.utils.command.CommandHandler;
|
||||||
import pro.gravit.utils.helper.JVMHelper;
|
import pro.gravit.utils.helper.JVMHelper;
|
||||||
|
@ -43,9 +42,6 @@ public void invoke(String... args) {
|
||||||
}
|
}
|
||||||
logger.info("Commands: {}({} categories)", commands, server.commandHandler.getCategories().size() + 1);
|
logger.info("Commands: {}({} categories)", commands, server.commandHandler.getCategories().size() + 1);
|
||||||
for (AuthProviderPair pair : server.config.auth.values()) {
|
for (AuthProviderPair pair : server.config.auth.values()) {
|
||||||
if (pair.handler instanceof CachedAuthHandler) {
|
|
||||||
logger.info("AuthHandler {}: EntryCache: {} | usernameCache: {}", pair.name, ((CachedAuthHandler) pair.handler).getEntryCache().size(), ((CachedAuthHandler) pair.handler).getUsernamesCache().size());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
package pro.gravit.launchserver.command.service;
|
||||||
|
|
||||||
|
import io.jsonwebtoken.Jwts;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import pro.gravit.launchserver.LaunchServer;
|
||||||
|
import pro.gravit.launchserver.command.Command;
|
||||||
|
import pro.gravit.utils.command.SubCommand;
|
||||||
|
|
||||||
|
public class TokenCommand extends Command {
|
||||||
|
private transient final Logger logger = LogManager.getLogger();
|
||||||
|
public TokenCommand(LaunchServer server) {
|
||||||
|
super(server);
|
||||||
|
this.childCommands.put("info", new SubCommand("[token]", "print token info") {
|
||||||
|
@Override
|
||||||
|
public void invoke(String... args) throws Exception {
|
||||||
|
verifyArgs(args, 1);
|
||||||
|
var parser = Jwts.parserBuilder().setSigningKey(server.keyAgreementManager.ecdsaPublicKey).build();
|
||||||
|
var claims = parser.parseClaimsJws(args[0]);
|
||||||
|
logger.info("Token: {}", claims.getBody());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.childCommands.put("server", new SubCommand("[serverName] (authId)", "generate new server token") {
|
||||||
|
@Override
|
||||||
|
public void invoke(String... args) throws Exception {
|
||||||
|
String token = server.authManager.newCheckServerToken(args[0], args.length > 1 ? args[1] : server.config.getAuthProviderPair().name);
|
||||||
|
logger.info("Token: {}", token);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getArgsDescription() {
|
||||||
|
return "[new/info/token name] [args]";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUsageDescription() {
|
||||||
|
return "jwt management";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void invoke(String... args) throws Exception {
|
||||||
|
invokeSubcommands(args);
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,19 +19,9 @@ public static void registerComponents() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public void preInit(LaunchServer launchServer) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract void init(LaunchServer launchServer);
|
public abstract void init(LaunchServer launchServer);
|
||||||
|
|
||||||
public final void setComponentName(String s) {
|
public final void setComponentName(String s) {
|
||||||
this.componentName = s;
|
this.componentName = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public void postInit(LaunchServer launchServer) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
import pro.gravit.launchserver.components.Component;
|
import pro.gravit.launchserver.components.Component;
|
||||||
import pro.gravit.launchserver.components.ProGuardComponent;
|
import pro.gravit.launchserver.components.ProGuardComponent;
|
||||||
import pro.gravit.launchserver.components.RegLimiterComponent;
|
import pro.gravit.launchserver.components.RegLimiterComponent;
|
||||||
import pro.gravit.launchserver.dao.provider.DaoProvider;
|
|
||||||
import pro.gravit.utils.Version;
|
import pro.gravit.utils.Version;
|
||||||
import pro.gravit.utils.helper.JVMHelper;
|
import pro.gravit.utils.helper.JVMHelper;
|
||||||
|
|
||||||
|
@ -37,8 +36,6 @@ public final class LaunchServerConfig {
|
||||||
public boolean cacheUpdates = true;
|
public boolean cacheUpdates = true;
|
||||||
public LauncherConfig.LauncherEnvironment env;
|
public LauncherConfig.LauncherEnvironment env;
|
||||||
public Map<String, AuthProviderPair> auth;
|
public Map<String, AuthProviderPair> auth;
|
||||||
@Deprecated
|
|
||||||
public DaoProvider dao;
|
|
||||||
public SessionStorage sessions;
|
public SessionStorage sessions;
|
||||||
// Handlers & Providers
|
// Handlers & Providers
|
||||||
public ProtectHandler protectHandler;
|
public ProtectHandler protectHandler;
|
||||||
|
@ -154,10 +151,6 @@ public void verify() {
|
||||||
throw new NullPointerException("AuthProviderPair`s count should be at least one");
|
throw new NullPointerException("AuthProviderPair`s count should be at least one");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dao != null) {
|
|
||||||
logger.warn("DAO deprecated and may be remove in future release");
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean isOneDefault = false;
|
boolean isOneDefault = false;
|
||||||
for (AuthProviderPair pair : auth.values()) {
|
for (AuthProviderPair pair : auth.values()) {
|
||||||
if (pair.isDefault) {
|
if (pair.isDefault) {
|
||||||
|
@ -183,13 +176,6 @@ public void init(LaunchServer.ReloadType type) {
|
||||||
Launcher.applyLauncherEnv(env);
|
Launcher.applyLauncherEnv(env);
|
||||||
for (Map.Entry<String, AuthProviderPair> provider : auth.entrySet()) {
|
for (Map.Entry<String, AuthProviderPair> provider : auth.entrySet()) {
|
||||||
provider.getValue().init(server, provider.getKey());
|
provider.getValue().init(server, provider.getKey());
|
||||||
if (!provider.getValue().isUseCore()) {
|
|
||||||
logger.warn("Deprecated auth {}: legacy provider/handler auth may be removed in future release", provider.getKey());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (dao != null) {
|
|
||||||
server.registerObject("dao", dao);
|
|
||||||
dao.init(server);
|
|
||||||
}
|
}
|
||||||
if (protectHandler != null) {
|
if (protectHandler != null) {
|
||||||
server.registerObject("protectHandler", protectHandler);
|
server.registerObject("protectHandler", protectHandler);
|
||||||
|
@ -205,8 +191,6 @@ public void init(LaunchServer.ReloadType type) {
|
||||||
}
|
}
|
||||||
if (!type.equals(LaunchServer.ReloadType.NO_AUTH)) {
|
if (!type.equals(LaunchServer.ReloadType.NO_AUTH)) {
|
||||||
for (AuthProviderPair pair : auth.values()) {
|
for (AuthProviderPair pair : auth.values()) {
|
||||||
server.registerObject("auth.".concat(pair.name).concat(".provider"), pair.provider);
|
|
||||||
server.registerObject("auth.".concat(pair.name).concat(".handler"), pair.handler);
|
|
||||||
server.registerObject("auth.".concat(pair.name).concat(".core"), pair.core);
|
server.registerObject("auth.".concat(pair.name).concat(".core"), pair.core);
|
||||||
server.registerObject("auth.".concat(pair.name).concat(".social"), pair.social);
|
server.registerObject("auth.".concat(pair.name).concat(".social"), pair.social);
|
||||||
server.registerObject("auth.".concat(pair.name).concat(".texture"), pair.textureProvider);
|
server.registerObject("auth.".concat(pair.name).concat(".texture"), pair.textureProvider);
|
||||||
|
@ -219,8 +203,6 @@ public void close(LaunchServer.ReloadType type) {
|
||||||
try {
|
try {
|
||||||
if (!type.equals(LaunchServer.ReloadType.NO_AUTH)) {
|
if (!type.equals(LaunchServer.ReloadType.NO_AUTH)) {
|
||||||
for (AuthProviderPair pair : auth.values()) {
|
for (AuthProviderPair pair : auth.values()) {
|
||||||
server.unregisterObject("auth.".concat(pair.name).concat(".provider"), pair.provider);
|
|
||||||
server.unregisterObject("auth.".concat(pair.name).concat(".handler"), pair.handler);
|
|
||||||
server.unregisterObject("auth.".concat(pair.name).concat(".social"), pair.social);
|
server.unregisterObject("auth.".concat(pair.name).concat(".social"), pair.social);
|
||||||
server.unregisterObject("auth.".concat(pair.name).concat(".core"), pair.core);
|
server.unregisterObject("auth.".concat(pair.name).concat(".core"), pair.core);
|
||||||
server.unregisterObject("auth.".concat(pair.name).concat(".texture"), pair.textureProvider);
|
server.unregisterObject("auth.".concat(pair.name).concat(".texture"), pair.textureProvider);
|
||||||
|
@ -256,16 +238,6 @@ public void close(LaunchServer.ReloadType type) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (dao != null) {
|
|
||||||
server.unregisterObject("dao", dao);
|
|
||||||
if (dao instanceof AutoCloseable) {
|
|
||||||
try {
|
|
||||||
((AutoCloseable) dao).close();
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.error(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ExeConf {
|
public static class ExeConf {
|
||||||
|
@ -307,8 +279,6 @@ public static class NettyUpdatesBind {
|
||||||
public static class LauncherConf {
|
public static class LauncherConf {
|
||||||
public String guardType;
|
public String guardType;
|
||||||
public boolean compress;
|
public boolean compress;
|
||||||
@Deprecated
|
|
||||||
public boolean warningMissArchJava;
|
|
||||||
public boolean stripLineNumbers;
|
public boolean stripLineNumbers;
|
||||||
public boolean deleteTempFiles;
|
public boolean deleteTempFiles;
|
||||||
public boolean certificatePinning;
|
public boolean certificatePinning;
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
package pro.gravit.launchserver.dao;
|
|
||||||
|
|
||||||
import pro.gravit.launcher.ClientPermissions;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public interface User {
|
|
||||||
String getUsername();
|
|
||||||
|
|
||||||
ClientPermissions getPermissions();
|
|
||||||
|
|
||||||
void setPermissions(ClientPermissions permissions);
|
|
||||||
|
|
||||||
boolean verifyPassword(String password);
|
|
||||||
|
|
||||||
void setPassword(String password);
|
|
||||||
|
|
||||||
String getAccessToken();
|
|
||||||
|
|
||||||
void setAccessToken(String accessToken);
|
|
||||||
|
|
||||||
String getServerID();
|
|
||||||
|
|
||||||
void setServerID(String serverID);
|
|
||||||
|
|
||||||
UUID getUuid();
|
|
||||||
|
|
||||||
void setUuid(UUID uuid);
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
package pro.gravit.launchserver.dao;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public interface UserDAO {
|
|
||||||
User findById(int id);
|
|
||||||
|
|
||||||
User findByUsername(String username);
|
|
||||||
|
|
||||||
User findByUUID(UUID uuid);
|
|
||||||
|
|
||||||
void save(User user);
|
|
||||||
|
|
||||||
void update(User user);
|
|
||||||
|
|
||||||
void delete(User user);
|
|
||||||
|
|
||||||
List<User> findAll();
|
|
||||||
}
|
|
|
@ -1,17 +0,0 @@
|
||||||
package pro.gravit.launchserver.dao.provider;
|
|
||||||
|
|
||||||
import pro.gravit.launchserver.LaunchServer;
|
|
||||||
import pro.gravit.launchserver.dao.UserDAO;
|
|
||||||
import pro.gravit.utils.ProviderMap;
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public abstract class DaoProvider {
|
|
||||||
public static final ProviderMap<DaoProvider> providers = new ProviderMap<>("DaoProvider");
|
|
||||||
public transient UserDAO userDAO;
|
|
||||||
|
|
||||||
public static void registerProviders() {
|
|
||||||
// None
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract void init(LaunchServer server);
|
|
||||||
}
|
|
|
@ -1,129 +0,0 @@
|
||||||
package pro.gravit.launchserver.dao.provider;
|
|
||||||
|
|
||||||
import org.hibernate.SessionFactory;
|
|
||||||
import org.hibernate.cfg.Configuration;
|
|
||||||
import pro.gravit.launcher.ClientPermissions;
|
|
||||||
import pro.gravit.launchserver.LaunchServer;
|
|
||||||
import pro.gravit.launchserver.Reconfigurable;
|
|
||||||
import pro.gravit.launchserver.dao.User;
|
|
||||||
import pro.gravit.launchserver.dao.UserDAO;
|
|
||||||
import pro.gravit.utils.command.Command;
|
|
||||||
import pro.gravit.utils.command.SubCommand;
|
|
||||||
import pro.gravit.utils.helper.CommonHelper;
|
|
||||||
import pro.gravit.utils.helper.LogHelper;
|
|
||||||
|
|
||||||
import java.nio.file.Paths;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Deprecated from 5.2.0
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public abstract class HibernateDaoProvider extends DaoProvider implements Reconfigurable, AutoCloseable {
|
|
||||||
public String driver;
|
|
||||||
public String url;
|
|
||||||
public String username;
|
|
||||||
public String password;
|
|
||||||
public String dialect;
|
|
||||||
public String pool_size;
|
|
||||||
public String hibernateConfig;
|
|
||||||
public boolean parallelHibernateInit;
|
|
||||||
protected transient SessionFactory sessionFactory;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init(LaunchServer server) {
|
|
||||||
Runnable init = () -> {
|
|
||||||
Configuration cfg = new Configuration()
|
|
||||||
//.addAnnotatedClass(UserHibernateImpl.class)
|
|
||||||
.setProperty("hibernate.connection.driver_class", driver)
|
|
||||||
.setProperty("hibernate.connection.url", url)
|
|
||||||
.setProperty("hibernate.connection.username", username)
|
|
||||||
.setProperty("hibernate.connection.password", password)
|
|
||||||
.setProperty("hibernate.connection.pool_size", pool_size);
|
|
||||||
if (dialect != null)
|
|
||||||
cfg.setProperty("hibernate.dialect", dialect);
|
|
||||||
if (hibernateConfig != null)
|
|
||||||
cfg.configure(Paths.get(hibernateConfig).toFile());
|
|
||||||
onConfigure(cfg);
|
|
||||||
sessionFactory = cfg.buildSessionFactory();
|
|
||||||
userDAO = newUserDAO();
|
|
||||||
};
|
|
||||||
if (parallelHibernateInit)
|
|
||||||
CommonHelper.newThread("Hibernate Thread", true, init);
|
|
||||||
else
|
|
||||||
init.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract void onConfigure(Configuration configuration);
|
|
||||||
|
|
||||||
protected abstract UserDAO newUserDAO();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, Command> getCommands() {
|
|
||||||
Map<String, Command> commands = new HashMap<>();
|
|
||||||
commands.put("getallusers", new SubCommand() {
|
|
||||||
@Override
|
|
||||||
public void invoke(String... args) {
|
|
||||||
int count = 0;
|
|
||||||
for (User user : userDAO.findAll()) {
|
|
||||||
LogHelper.subInfo("[%s] UUID: %s", user.getUsername(), user.getUuid().toString());
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
LogHelper.info("Print %d users", count);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
commands.put("getuser", new SubCommand() {
|
|
||||||
@Override
|
|
||||||
public void invoke(String... args) throws Exception {
|
|
||||||
verifyArgs(args, 1);
|
|
||||||
User user = userDAO.findByUsername(args[0]);
|
|
||||||
if (user == null) {
|
|
||||||
LogHelper.error("User %s not found", args[0]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
LogHelper.info("[%s] UUID: %s | permissions %s", user.getUsername(), user.getUuid().toString(), user.getPermissions() == null ? "null" : user.getPermissions().toString());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
commands.put("givepermission", new SubCommand() {
|
|
||||||
@Override
|
|
||||||
public void invoke(String... args) throws Exception {
|
|
||||||
verifyArgs(args, 3);
|
|
||||||
User user = userDAO.findByUsername(args[0]);
|
|
||||||
if (user == null) {
|
|
||||||
LogHelper.error("User %s not found", args[0]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ClientPermissions permissions = user.getPermissions();
|
|
||||||
long perm = Long.parseLong(args[1]);
|
|
||||||
boolean value = Boolean.parseBoolean(args[2]);
|
|
||||||
permissions.setPermission(perm, value);
|
|
||||||
user.setPermissions(permissions);
|
|
||||||
userDAO.update(user);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
commands.put("giveflag", new SubCommand() {
|
|
||||||
@Override
|
|
||||||
public void invoke(String... args) throws Exception {
|
|
||||||
verifyArgs(args, 3);
|
|
||||||
User user = userDAO.findByUsername(args[0]);
|
|
||||||
if (user == null) {
|
|
||||||
LogHelper.error("User %s not found", args[0]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ClientPermissions permissions = user.getPermissions();
|
|
||||||
long perm = Long.parseLong(args[1]);
|
|
||||||
boolean value = Boolean.parseBoolean(args[2]);
|
|
||||||
permissions.setFlag(perm, value);
|
|
||||||
user.setPermissions(permissions);
|
|
||||||
userDAO.update(user);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return commands;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
sessionFactory.close();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,172 @@
|
||||||
|
package pro.gravit.launchserver.helper;
|
||||||
|
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import pro.gravit.launcher.Launcher;
|
||||||
|
import pro.gravit.launcher.request.RequestException;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.net.http.HttpClient;
|
||||||
|
import java.net.http.HttpRequest;
|
||||||
|
import java.net.http.HttpResponse;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.CompletionStage;
|
||||||
|
import java.util.concurrent.Flow;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
public final class HttpHelper {
|
||||||
|
private static transient final Logger logger = LogManager.getLogger();
|
||||||
|
private HttpHelper() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class HttpOptional<T,E> {
|
||||||
|
protected final T result;
|
||||||
|
protected final E error;
|
||||||
|
protected final int statusCode;
|
||||||
|
|
||||||
|
public HttpOptional(T result, E error, int statusCode) {
|
||||||
|
this.result = result;
|
||||||
|
this.error = error;
|
||||||
|
this.statusCode = statusCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T result() {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
public E error() {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
public int statusCode() {
|
||||||
|
return statusCode;
|
||||||
|
}
|
||||||
|
public boolean isSuccessful() {
|
||||||
|
return statusCode >= 200 && statusCode < 300;
|
||||||
|
}
|
||||||
|
public T getOrThrow() throws RequestException {
|
||||||
|
if(isSuccessful()) {
|
||||||
|
return result;
|
||||||
|
} else {
|
||||||
|
throw new RequestException(error == null ? String.format("statusCode %d", statusCode) : error.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface HttpErrorHandler<T, E> {
|
||||||
|
HttpOptional<T,E> apply(HttpResponse<InputStream> response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface HttpJsonErrorHandler<T, E> extends HttpErrorHandler<T,E> {
|
||||||
|
HttpOptional<T,E> applyJson(JsonElement response, int statusCode);
|
||||||
|
default HttpOptional<T,E> apply(HttpResponse<InputStream> response) {
|
||||||
|
try(Reader reader = new InputStreamReader(response.body())) {
|
||||||
|
var element = Launcher.gsonManager.gson.fromJson(reader, JsonElement.class);
|
||||||
|
return applyJson(element, response.statusCode());
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class BasicJsonHttpErrorHandler<T> implements HttpJsonErrorHandler<T, Void> {
|
||||||
|
private final Class<T> type;
|
||||||
|
|
||||||
|
public BasicJsonHttpErrorHandler(Class<T> type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HttpOptional<T, Void> applyJson(JsonElement response, int statusCode) {
|
||||||
|
return new HttpOptional<>(Launcher.gsonManager.gson.fromJson(response, type), null, statusCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static<T,E> HttpOptional<T,E> send(HttpClient client, HttpRequest request, HttpErrorHandler<T,E> handler) throws IOException {
|
||||||
|
try {
|
||||||
|
var response = client.send(request, HttpResponse.BodyHandlers.ofInputStream());
|
||||||
|
return handler.apply(response);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw new IOException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static<T,E> CompletableFuture<HttpOptional<T,E>> sendAsync(HttpClient client, HttpRequest request, HttpErrorHandler<T,E> handler) throws IOException {
|
||||||
|
return client.sendAsync(request, HttpResponse.BodyHandlers.ofInputStream()).thenApply(handler::apply);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static<T> HttpResponse.BodyHandler<T> ofJsonResult(Class<T> type) {
|
||||||
|
return ofJsonResult((Type) type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static<T> HttpResponse.BodyHandler<T> ofJsonResult(Type type) {
|
||||||
|
return new JsonBodyHandler<>(HttpResponse.BodyHandlers.ofInputStream(), (input) -> {
|
||||||
|
try(Reader reader = new InputStreamReader(input)) {
|
||||||
|
return Launcher.gsonManager.gson.fromJson(reader, type);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static<T> HttpRequest.BodyPublisher jsonBodyPublisher(T obj) {
|
||||||
|
return HttpRequest.BodyPublishers.ofString(Launcher.gsonManager.gson.toJson(obj));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class JsonBodyHandler<T> implements HttpResponse.BodyHandler<T> {
|
||||||
|
private final HttpResponse.BodyHandler<InputStream> delegate;
|
||||||
|
private final Function<InputStream, T> func;
|
||||||
|
|
||||||
|
private JsonBodyHandler(HttpResponse.BodyHandler<InputStream> delegate, Function<InputStream, T> func) {
|
||||||
|
this.delegate = delegate;
|
||||||
|
this.func = func;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HttpResponse.BodySubscriber<T> apply(HttpResponse.ResponseInfo responseInfo) {
|
||||||
|
return new JsonBodySubscriber<>(delegate.apply(responseInfo), func);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class JsonBodySubscriber<T> implements HttpResponse.BodySubscriber<T> {
|
||||||
|
private final HttpResponse.BodySubscriber<InputStream> delegate;
|
||||||
|
private final Function<InputStream, T> func;
|
||||||
|
|
||||||
|
private JsonBodySubscriber(HttpResponse.BodySubscriber<InputStream> delegate, Function<InputStream, T> func) {
|
||||||
|
this.delegate = delegate;
|
||||||
|
this.func = func;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompletionStage<T> getBody() {
|
||||||
|
return delegate.getBody().thenApply(func);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSubscribe(Flow.Subscription subscription) {
|
||||||
|
delegate.onSubscribe(subscription);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNext(List<ByteBuffer> item) {
|
||||||
|
delegate.onNext(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(Throwable throwable) {
|
||||||
|
delegate.onError(throwable);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onComplete() {
|
||||||
|
delegate.onComplete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -24,7 +24,7 @@ public static ClientProfile makeProfile(ClientProfile.Version version, String ti
|
||||||
builder.setTitle(title);
|
builder.setTitle(title);
|
||||||
builder.setUuid(UUID.randomUUID());
|
builder.setUuid(UUID.randomUUID());
|
||||||
builder.setMainClass(getMainClassByVersion(version, options));
|
builder.setMainClass(getMainClassByVersion(version, options));
|
||||||
builder.setServers(List.of(new ClientProfile.ServerProfile(title, "localhost", 25535)));
|
builder.setServers(List.of(new ClientProfile.ServerProfile(title, "localhost", 25565)));
|
||||||
// ------------
|
// ------------
|
||||||
builder.setUpdateVerify(List.of("libraries", "natives", "mods", "minecraft.jar", "forge.jar", "liteloader.jar"));
|
builder.setUpdateVerify(List.of("libraries", "natives", "mods", "minecraft.jar", "forge.jar", "liteloader.jar"));
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package pro.gravit.launchserver.manangers;
|
package pro.gravit.launchserver.manangers;
|
||||||
|
|
||||||
|
import io.jsonwebtoken.JwtParser;
|
||||||
|
import io.jsonwebtoken.Jwts;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import pro.gravit.launcher.ClientPermissions;
|
import pro.gravit.launcher.ClientPermissions;
|
||||||
|
@ -16,12 +18,10 @@
|
||||||
import pro.gravit.launchserver.auth.core.User;
|
import pro.gravit.launchserver.auth.core.User;
|
||||||
import pro.gravit.launchserver.auth.core.UserSession;
|
import pro.gravit.launchserver.auth.core.UserSession;
|
||||||
import pro.gravit.launchserver.auth.core.interfaces.user.UserSupportTextures;
|
import pro.gravit.launchserver.auth.core.interfaces.user.UserSupportTextures;
|
||||||
import pro.gravit.launchserver.auth.provider.AuthProvider;
|
|
||||||
import pro.gravit.launchserver.auth.provider.AuthProviderDAOResult;
|
|
||||||
import pro.gravit.launchserver.auth.provider.AuthProviderResult;
|
|
||||||
import pro.gravit.launchserver.auth.texture.TextureProvider;
|
import pro.gravit.launchserver.auth.texture.TextureProvider;
|
||||||
import pro.gravit.launchserver.socket.Client;
|
import pro.gravit.launchserver.socket.Client;
|
||||||
import pro.gravit.launchserver.socket.response.auth.AuthResponse;
|
import pro.gravit.launchserver.socket.response.auth.AuthResponse;
|
||||||
|
import pro.gravit.launchserver.socket.response.auth.RestoreResponse;
|
||||||
import pro.gravit.utils.helper.IOHelper;
|
import pro.gravit.utils.helper.IOHelper;
|
||||||
import pro.gravit.utils.helper.SecurityHelper;
|
import pro.gravit.utils.helper.SecurityHelper;
|
||||||
|
|
||||||
|
@ -36,9 +36,59 @@
|
||||||
public class AuthManager {
|
public class AuthManager {
|
||||||
private transient final LaunchServer server;
|
private transient final LaunchServer server;
|
||||||
private transient final Logger logger = LogManager.getLogger();
|
private transient final Logger logger = LogManager.getLogger();
|
||||||
|
private transient final JwtParser checkServerTokenParser;
|
||||||
|
|
||||||
public AuthManager(LaunchServer server) {
|
public AuthManager(LaunchServer server) {
|
||||||
this.server = server;
|
this.server = server;
|
||||||
|
this.checkServerTokenParser = Jwts.parserBuilder()
|
||||||
|
.requireIssuer("LaunchServer")
|
||||||
|
.require("tokenType", "checkServer")
|
||||||
|
.setSigningKey(server.keyAgreementManager.ecdsaPublicKey)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String newCheckServerToken(String serverName, String authId) {
|
||||||
|
return Jwts.builder()
|
||||||
|
.setIssuer("LaunchServer")
|
||||||
|
.claim("serverName", serverName)
|
||||||
|
.claim("authId", authId)
|
||||||
|
.claim("tokenType", "checkServer")
|
||||||
|
.signWith(server.keyAgreementManager.ecdsaPrivateKey)
|
||||||
|
.compact();
|
||||||
|
}
|
||||||
|
|
||||||
|
public record CheckServerTokenInfo(String serverName, String authId) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public CheckServerTokenInfo parseCheckServerToken(String token) {
|
||||||
|
try {
|
||||||
|
var jwt = checkServerTokenParser.parseClaimsJws(token).getBody();
|
||||||
|
return new CheckServerTokenInfo(jwt.get("serverName", String.class), jwt.get("authId", String.class));
|
||||||
|
} catch (Exception e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class CheckServerVerifier implements RestoreResponse.ExtendedTokenProvider {
|
||||||
|
private final LaunchServer server;
|
||||||
|
|
||||||
|
public CheckServerVerifier(LaunchServer server) {
|
||||||
|
this.server = server;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean accept(Client client, AuthProviderPair pair, String extendedToken) {
|
||||||
|
var info = server.authManager.parseCheckServerToken(extendedToken);
|
||||||
|
if(info == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
client.auth_id = info.authId;
|
||||||
|
client.auth = server.config.getAuthProviderPair(info.authId);
|
||||||
|
if(client.permissions == null) client.permissions = new ClientPermissions();
|
||||||
|
client.permissions.addPerm("launchserver.checkserver");
|
||||||
|
client.permissions.addPerm(String.format("launchserver.profiles.%s.show", info.serverName));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -61,12 +111,10 @@ public AuthResponse.AuthContext makeAuthContext(Client client, AuthResponse.Conn
|
||||||
*/
|
*/
|
||||||
public void check(AuthResponse.AuthContext context) throws AuthException {
|
public void check(AuthResponse.AuthContext context) throws AuthException {
|
||||||
if (context.authType == AuthResponse.ConnectTypes.CLIENT && !context.client.checkSign) {
|
if (context.authType == AuthResponse.ConnectTypes.CLIENT && !context.client.checkSign) {
|
||||||
AuthProvider.authError("Don't skip Launcher Update");
|
throw new AuthException("Don't skip Launcher Update");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
if (context.client.isAuth) {
|
if (context.client.isAuth) {
|
||||||
AuthProvider.authError("You are already logged in");
|
throw new AuthException("You are already logged in");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,47 +126,9 @@ public void check(AuthResponse.AuthContext context) throws AuthException {
|
||||||
* @return Access token
|
* @return Access token
|
||||||
*/
|
*/
|
||||||
public AuthReport auth(AuthResponse.AuthContext context, AuthRequest.AuthPasswordInterface password) throws AuthException {
|
public AuthReport auth(AuthResponse.AuthContext context, AuthRequest.AuthPasswordInterface password) throws AuthException {
|
||||||
AuthProviderPair pair = context.pair;
|
|
||||||
AuthReport report;
|
|
||||||
if (pair.core == null) {
|
|
||||||
try {
|
|
||||||
report = AuthReport.ofMinecraftAccessToken(authWithProviderAndHandler(context, password));
|
|
||||||
} catch (Exception e) {
|
|
||||||
if (e instanceof AuthException) throw (AuthException) e;
|
|
||||||
throw new AuthException("Internal Auth Error. Please contact administrator");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
report = authWithCore(context, password);
|
|
||||||
}
|
|
||||||
return report;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
private String authWithProviderAndHandler(AuthResponse.AuthContext context, AuthRequest.AuthPasswordInterface password) throws Exception {
|
|
||||||
String accessToken;
|
|
||||||
context.pair.provider.preAuth(context.login, password, context.ip);
|
|
||||||
AuthProviderResult aresult = context.pair.provider.auth(context.login, password, context.ip);
|
|
||||||
UUID uuid;
|
|
||||||
String username = aresult.username != null ? aresult.username : context.login;
|
|
||||||
if (aresult instanceof AuthProviderDAOResult) {
|
|
||||||
context.client.daoObject = ((AuthProviderDAOResult) aresult).daoObject;
|
|
||||||
}
|
|
||||||
if (context.authType == AuthResponse.ConnectTypes.CLIENT && server.config.protectHandler.allowGetAccessToken(context)) {
|
|
||||||
uuid = context.pair.handler.auth(aresult);
|
|
||||||
accessToken = aresult.accessToken;
|
|
||||||
} else {
|
|
||||||
uuid = context.pair.handler.usernameToUUID(aresult.username);
|
|
||||||
accessToken = null;
|
|
||||||
}
|
|
||||||
internalAuth(context.client, context.authType, context.pair, username, uuid, aresult.permissions, false);
|
|
||||||
return accessToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
private AuthReport authWithCore(AuthResponse.AuthContext context, AuthRequest.AuthPasswordInterface password) throws AuthException {
|
|
||||||
AuthCoreProvider provider = context.pair.core;
|
AuthCoreProvider provider = context.pair.core;
|
||||||
provider.verifyAuth(context);
|
provider.verifyAuth(context);
|
||||||
if (password instanceof AuthOAuthPassword) {
|
if (password instanceof AuthOAuthPassword password1) {
|
||||||
AuthOAuthPassword password1 = (AuthOAuthPassword) password;
|
|
||||||
UserSession session;
|
UserSession session;
|
||||||
try {
|
try {
|
||||||
session = provider.getUserSessionByOAuthAccessToken(password1.accessToken);
|
session = provider.getUserSessionByOAuthAccessToken(password1.accessToken);
|
||||||
|
@ -180,7 +190,7 @@ private AuthReport authWithCore(AuthResponse.AuthContext context, AuthRequest.Au
|
||||||
internalAuth(context.client, context.authType, context.pair, user.getUsername(), user.getUUID(), user.getPermissions(), result.isUsingOAuth());
|
internalAuth(context.client, context.authType, context.pair, user.getUsername(), user.getUUID(), user.getPermissions(), result.isUsingOAuth());
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
if (report.needMoreFactor) {
|
if (report.needMoreFactors) {
|
||||||
if (report.factors.size() == 1 && report.factors.get(0) == -1) {
|
if (report.factors.size() == 1 && report.factors.get(0) == -1) {
|
||||||
throw new AuthException(AuthRequestEvent.TWO_FACTOR_NEED_ERROR_MESSAGE);
|
throw new AuthException(AuthRequestEvent.TWO_FACTOR_NEED_ERROR_MESSAGE);
|
||||||
}
|
}
|
||||||
|
@ -196,6 +206,9 @@ private AuthReport authWithCore(AuthResponse.AuthContext context, AuthRequest.Au
|
||||||
* Writing authorization information to the Client object
|
* Writing authorization information to the Client object
|
||||||
*/
|
*/
|
||||||
public void internalAuth(Client client, AuthResponse.ConnectTypes authType, AuthProviderPair pair, String username, UUID uuid, ClientPermissions permissions, boolean oauth) {
|
public void internalAuth(Client client, AuthResponse.ConnectTypes authType, AuthProviderPair pair, String username, UUID uuid, ClientPermissions permissions, boolean oauth) {
|
||||||
|
if(!oauth) {
|
||||||
|
pair.internalShowOAuthWarnMessage();
|
||||||
|
}
|
||||||
client.isAuth = true;
|
client.isAuth = true;
|
||||||
client.permissions = permissions;
|
client.permissions = permissions;
|
||||||
client.auth_id = pair.name;
|
client.auth_id = pair.name;
|
||||||
|
@ -204,30 +217,19 @@ public void internalAuth(Client client, AuthResponse.ConnectTypes authType, Auth
|
||||||
client.type = authType;
|
client.type = authType;
|
||||||
client.uuid = uuid;
|
client.uuid = uuid;
|
||||||
client.useOAuth = oauth;
|
client.useOAuth = oauth;
|
||||||
if (pair.isUseCore() && client.coreObject == null) {
|
|
||||||
client.coreObject = pair.core.getUserByUUID(uuid);
|
client.coreObject = pair.core.getUserByUUID(uuid);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public CheckServerReport checkServer(Client client, String username, String serverID) throws IOException {
|
public CheckServerReport checkServer(Client client, String username, String serverID) throws IOException {
|
||||||
if (client.auth == null) return null;
|
if (client.auth == null) return null;
|
||||||
if (client.auth.isUseCore()) {
|
|
||||||
User user = client.auth.core.checkServer(client, username, serverID);
|
User user = client.auth.core.checkServer(client, username, serverID);
|
||||||
if (user == null) return null;
|
if (user == null) return null;
|
||||||
else return CheckServerReport.ofUser(user, getPlayerProfile(client.auth, user));
|
else return CheckServerReport.ofUser(user, getPlayerProfile(client.auth, user));
|
||||||
} else {
|
|
||||||
UUID uuid = client.auth.handler.checkServer(username, serverID);
|
|
||||||
return uuid == null ? null : CheckServerReport.ofUUID(uuid, getPlayerProfile(client.auth, uuid));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean joinServer(Client client, String username, String accessToken, String serverID) throws IOException {
|
public boolean joinServer(Client client, String username, String accessToken, String serverID) throws IOException {
|
||||||
if (client.auth == null) return false;
|
if (client.auth == null) return false;
|
||||||
if (client.auth.isUseCore()) {
|
|
||||||
return client.auth.core.joinServer(client, username, accessToken, serverID);
|
return client.auth.core.joinServer(client, username, accessToken, serverID);
|
||||||
} else {
|
|
||||||
return client.auth.handler.joinServer(username, accessToken, serverID);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public PlayerProfile getPlayerProfile(Client client) {
|
public PlayerProfile getPlayerProfile(Client client) {
|
||||||
|
@ -253,8 +255,7 @@ public PlayerProfile getPlayerProfile(AuthProviderPair pair, String username) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public PlayerProfile getPlayerProfile(AuthProviderPair pair, String username, ClientProfile profile) {
|
public PlayerProfile getPlayerProfile(AuthProviderPair pair, String username, ClientProfile profile) {
|
||||||
UUID uuid = null;
|
UUID uuid;
|
||||||
if (pair.isUseCore()) {
|
|
||||||
User user = pair.core.getUserByUsername(username);
|
User user = pair.core.getUserByUsername(username);
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -262,13 +263,6 @@ public PlayerProfile getPlayerProfile(AuthProviderPair pair, String username, Cl
|
||||||
PlayerProfile playerProfile = getPlayerProfile(pair, user);
|
PlayerProfile playerProfile = getPlayerProfile(pair, user);
|
||||||
uuid = user.getUUID();
|
uuid = user.getUUID();
|
||||||
if (playerProfile != null) return playerProfile;
|
if (playerProfile != null) return playerProfile;
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
uuid = pair.handler.usernameToUUID(username);
|
|
||||||
} catch (IOException e) {
|
|
||||||
logger.error("UsernameToUUID failed", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (uuid == null) {
|
if (uuid == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -283,8 +277,7 @@ public PlayerProfile getPlayerProfile(AuthProviderPair pair, UUID uuid) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public PlayerProfile getPlayerProfile(AuthProviderPair pair, UUID uuid, ClientProfile profile) {
|
public PlayerProfile getPlayerProfile(AuthProviderPair pair, UUID uuid, ClientProfile profile) {
|
||||||
String username = null;
|
String username;
|
||||||
if (pair.isUseCore()) {
|
|
||||||
User user = pair.core.getUserByUUID(uuid);
|
User user = pair.core.getUserByUUID(uuid);
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -292,13 +285,6 @@ public PlayerProfile getPlayerProfile(AuthProviderPair pair, UUID uuid, ClientPr
|
||||||
PlayerProfile playerProfile = getPlayerProfile(pair, user);
|
PlayerProfile playerProfile = getPlayerProfile(pair, user);
|
||||||
username = user.getUsername();
|
username = user.getUsername();
|
||||||
if (playerProfile != null) return playerProfile;
|
if (playerProfile != null) return playerProfile;
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
username = pair.handler.uuidToUsername(uuid);
|
|
||||||
} catch (IOException e) {
|
|
||||||
logger.error("UUIDToUsername failed", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (username == null) {
|
if (username == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -327,12 +313,10 @@ private PlayerProfile getPlayerProfile(UUID uuid, String username, String client
|
||||||
}
|
}
|
||||||
|
|
||||||
public AuthRequest.AuthPasswordInterface decryptPassword(AuthRequest.AuthPasswordInterface password) throws AuthException {
|
public AuthRequest.AuthPasswordInterface decryptPassword(AuthRequest.AuthPasswordInterface password) throws AuthException {
|
||||||
if (password instanceof Auth2FAPassword) {
|
if (password instanceof Auth2FAPassword auth2FAPassword) {
|
||||||
Auth2FAPassword auth2FAPassword = (Auth2FAPassword) password;
|
|
||||||
auth2FAPassword.firstPassword = tryDecryptPasswordPlain(auth2FAPassword.firstPassword);
|
auth2FAPassword.firstPassword = tryDecryptPasswordPlain(auth2FAPassword.firstPassword);
|
||||||
auth2FAPassword.secondPassword = tryDecryptPasswordPlain(auth2FAPassword.secondPassword);
|
auth2FAPassword.secondPassword = tryDecryptPasswordPlain(auth2FAPassword.secondPassword);
|
||||||
} else if (password instanceof AuthMultiPassword) {
|
} else if (password instanceof AuthMultiPassword multiPassword) {
|
||||||
AuthMultiPassword multiPassword = (AuthMultiPassword) password;
|
|
||||||
List<AuthRequest.AuthPasswordInterface> list = new ArrayList<>(multiPassword.list.size());
|
List<AuthRequest.AuthPasswordInterface> list = new ArrayList<>(multiPassword.list.size());
|
||||||
for (AuthRequest.AuthPasswordInterface p : multiPassword.list) {
|
for (AuthRequest.AuthPasswordInterface p : multiPassword.list) {
|
||||||
list.add(tryDecryptPasswordPlain(p));
|
list.add(tryDecryptPasswordPlain(p));
|
||||||
|
@ -344,16 +328,7 @@ public AuthRequest.AuthPasswordInterface decryptPassword(AuthRequest.AuthPasswor
|
||||||
return password;
|
return password;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
private AuthRequest.AuthPasswordInterface tryDecryptPasswordPlain(AuthRequest.AuthPasswordInterface password) throws AuthException {
|
private AuthRequest.AuthPasswordInterface tryDecryptPasswordPlain(AuthRequest.AuthPasswordInterface password) throws AuthException {
|
||||||
if (password instanceof AuthECPassword) {
|
|
||||||
try {
|
|
||||||
return new AuthPlainPassword(IOHelper.decode(SecurityHelper.decrypt(server.runtime.passwordEncryptKey
|
|
||||||
, ((AuthECPassword) password).password)));
|
|
||||||
} catch (Exception ignored) {
|
|
||||||
throw new AuthException("Password decryption error");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (password instanceof AuthAESPassword) {
|
if (password instanceof AuthAESPassword) {
|
||||||
try {
|
try {
|
||||||
return new AuthPlainPassword(IOHelper.decode(SecurityHelper.decrypt(server.runtime.passwordEncryptKey
|
return new AuthPlainPassword(IOHelper.decode(SecurityHelper.decrypt(server.runtime.passwordEncryptKey
|
||||||
|
@ -395,20 +370,9 @@ public static CheckServerReport ofUUID(UUID uuid, PlayerProfile playerProfile) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class AuthReport {
|
public record AuthReport(String minecraftAccessToken, String oauthAccessToken,
|
||||||
public final String minecraftAccessToken;
|
String oauthRefreshToken, long oauthExpire,
|
||||||
public final String oauthAccessToken;
|
UserSession session) {
|
||||||
public final String oauthRefreshToken;
|
|
||||||
public final long oauthExpire;
|
|
||||||
public final UserSession session;
|
|
||||||
|
|
||||||
public AuthReport(String minecraftAccessToken, String oauthAccessToken, String oauthRefreshToken, long oauthExpire, UserSession session) {
|
|
||||||
this.minecraftAccessToken = minecraftAccessToken;
|
|
||||||
this.oauthAccessToken = oauthAccessToken;
|
|
||||||
this.oauthRefreshToken = oauthRefreshToken;
|
|
||||||
this.oauthExpire = oauthExpire;
|
|
||||||
this.session = session;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static AuthReport ofOAuth(String oauthAccessToken, String oauthRefreshToken, long oauthExpire) {
|
public static AuthReport ofOAuth(String oauthAccessToken, String oauthRefreshToken, long oauthExpire) {
|
||||||
return new AuthReport(null, oauthAccessToken, oauthRefreshToken, oauthExpire, null);
|
return new AuthReport(null, oauthAccessToken, oauthRefreshToken, oauthExpire, null);
|
||||||
|
|
|
@ -4,118 +4,31 @@
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
|
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
|
||||||
import org.bouncycastle.asn1.x500.X500Name;
|
|
||||||
import org.bouncycastle.asn1.x500.X500NameBuilder;
|
|
||||||
import org.bouncycastle.asn1.x500.style.BCStyle;
|
|
||||||
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
|
|
||||||
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
|
|
||||||
import org.bouncycastle.cert.X509CertificateHolder;
|
import org.bouncycastle.cert.X509CertificateHolder;
|
||||||
import org.bouncycastle.cert.X509v3CertificateBuilder;
|
|
||||||
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
|
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
|
||||||
import org.bouncycastle.crypto.util.PrivateKeyFactory;
|
import org.bouncycastle.crypto.util.PrivateKeyFactory;
|
||||||
import org.bouncycastle.crypto.util.PrivateKeyInfoFactory;
|
import org.bouncycastle.crypto.util.PrivateKeyInfoFactory;
|
||||||
import org.bouncycastle.operator.ContentSigner;
|
|
||||||
import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder;
|
|
||||||
import org.bouncycastle.operator.OperatorCreationException;
|
|
||||||
import org.bouncycastle.operator.bc.BcECContentSignerBuilder;
|
|
||||||
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
|
|
||||||
import org.bouncycastle.util.io.pem.PemObject;
|
import org.bouncycastle.util.io.pem.PemObject;
|
||||||
import org.bouncycastle.util.io.pem.PemReader;
|
import org.bouncycastle.util.io.pem.PemReader;
|
||||||
import org.bouncycastle.util.io.pem.PemWriter;
|
import org.bouncycastle.util.io.pem.PemWriter;
|
||||||
import pro.gravit.launcher.LauncherTrustManager;
|
import pro.gravit.launcher.LauncherTrustManager;
|
||||||
import pro.gravit.utils.helper.IOHelper;
|
import pro.gravit.utils.helper.IOHelper;
|
||||||
import pro.gravit.utils.helper.JVMHelper;
|
import pro.gravit.utils.helper.JVMHelper;
|
||||||
import pro.gravit.utils.helper.SecurityHelper;
|
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.nio.file.*;
|
import java.nio.file.*;
|
||||||
import java.nio.file.attribute.BasicFileAttributes;
|
import java.nio.file.attribute.BasicFileAttributes;
|
||||||
import java.security.*;
|
import java.security.PrivateKey;
|
||||||
import java.security.cert.CertificateException;
|
import java.security.cert.CertificateException;
|
||||||
import java.security.cert.CertificateFactory;
|
import java.security.cert.CertificateFactory;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.security.spec.ECGenParameterSpec;
|
|
||||||
import java.time.Instant;
|
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.time.ZoneId;
|
|
||||||
import java.time.temporal.ChronoUnit;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class CertificateManager {
|
public class CertificateManager {
|
||||||
@Deprecated
|
|
||||||
public final int validDays = 60;
|
|
||||||
@Deprecated
|
|
||||||
public final int minusHours = 6;
|
|
||||||
private transient final Logger logger = LogManager.getLogger();
|
private transient final Logger logger = LogManager.getLogger();
|
||||||
@Deprecated
|
|
||||||
public X509CertificateHolder ca;
|
|
||||||
@Deprecated
|
|
||||||
public AsymmetricKeyParameter caKey;
|
|
||||||
@Deprecated
|
|
||||||
public X509CertificateHolder server;
|
|
||||||
@Deprecated
|
|
||||||
public AsymmetricKeyParameter serverKey;
|
|
||||||
public LauncherTrustManager trustManager;
|
public LauncherTrustManager trustManager;
|
||||||
@Deprecated
|
|
||||||
public String orgName;
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public X509CertificateHolder generateCertificate(String subjectName, PublicKey subjectPublicKey) throws OperatorCreationException {
|
|
||||||
SubjectPublicKeyInfo subjectPubKeyInfo = SubjectPublicKeyInfo.getInstance(subjectPublicKey.getEncoded());
|
|
||||||
BigInteger serial = BigInteger.valueOf(SecurityHelper.newRandom().nextLong());
|
|
||||||
Date startDate = Date.from(Instant.now().minus(minusHours, ChronoUnit.HOURS));
|
|
||||||
Date endDate = Date.from(startDate.toInstant().plus(validDays, ChronoUnit.DAYS));
|
|
||||||
|
|
||||||
X500NameBuilder subject = new X500NameBuilder();
|
|
||||||
subject.addRDN(BCStyle.CN, subjectName);
|
|
||||||
subject.addRDN(BCStyle.O, orgName);
|
|
||||||
X509v3CertificateBuilder v3CertGen = new X509v3CertificateBuilder(ca.getSubject(), serial,
|
|
||||||
startDate, endDate, subject.build(), subjectPubKeyInfo);
|
|
||||||
|
|
||||||
AlgorithmIdentifier sigAlgId = ca.getSignatureAlgorithm();
|
|
||||||
AlgorithmIdentifier digAlgId = new DefaultDigestAlgorithmIdentifierFinder().find(sigAlgId);
|
|
||||||
ContentSigner sigGen = new BcECContentSignerBuilder(sigAlgId, digAlgId).build(caKey);
|
|
||||||
|
|
||||||
return v3CertGen.build(sigGen);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public void generateCA() throws NoSuchAlgorithmException, IOException, OperatorCreationException, InvalidAlgorithmParameterException {
|
|
||||||
ECGenParameterSpec ecGenSpec = new ECGenParameterSpec("secp384k1");
|
|
||||||
KeyPairGenerator generator = KeyPairGenerator.getInstance("EC");
|
|
||||||
generator.initialize(ecGenSpec, SecurityHelper.newRandom());
|
|
||||||
KeyPair pair = generator.generateKeyPair();
|
|
||||||
LocalDateTime startDate = LocalDate.now().atStartOfDay();
|
|
||||||
|
|
||||||
X500NameBuilder subject = new X500NameBuilder();
|
|
||||||
subject.addRDN(BCStyle.CN, orgName.concat(" CA"));
|
|
||||||
subject.addRDN(BCStyle.O, orgName);
|
|
||||||
|
|
||||||
X509v3CertificateBuilder builder = new X509v3CertificateBuilder(
|
|
||||||
subject.build(),
|
|
||||||
new BigInteger("0"),
|
|
||||||
Date.from(startDate.atZone(ZoneId.systemDefault()).toInstant()),
|
|
||||||
Date.from(startDate.plusDays(3650).atZone(ZoneId.systemDefault()).toInstant()),
|
|
||||||
new X500Name("CN=ca"),
|
|
||||||
SubjectPublicKeyInfo.getInstance(pair.getPublic().getEncoded()));
|
|
||||||
JcaContentSignerBuilder csBuilder = new JcaContentSignerBuilder("SHA256WITHECDSA");
|
|
||||||
ContentSigner signer = csBuilder.build(pair.getPrivate());
|
|
||||||
ca = builder.build(signer);
|
|
||||||
caKey = PrivateKeyFactory.createKey(pair.getPrivate().getEncoded());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public KeyPair generateKeyPair() throws InvalidAlgorithmParameterException, NoSuchAlgorithmException {
|
|
||||||
ECGenParameterSpec ecGenSpec = new ECGenParameterSpec("secp384k1");
|
|
||||||
KeyPairGenerator generator = KeyPairGenerator.getInstance("EC");
|
|
||||||
generator.initialize(ecGenSpec, SecurityHelper.newRandom());
|
|
||||||
return generator.generateKeyPair();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void writePrivateKey(Path file, PrivateKey privateKey) throws IOException {
|
public void writePrivateKey(Path file, PrivateKey privateKey) throws IOException {
|
||||||
writePrivateKey(IOHelper.newWriter(file), privateKey);
|
writePrivateKey(IOHelper.newWriter(file), privateKey);
|
||||||
|
@ -214,24 +127,6 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IO
|
||||||
trustManager = new LauncherTrustManager(certificates.toArray(new X509Certificate[0]));
|
trustManager = new LauncherTrustManager(certificates.toArray(new X509Certificate[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public void checkClass(Class<?> clazz, LauncherTrustManager.CheckMode mode) throws SecurityException {
|
|
||||||
if (trustManager == null) return;
|
|
||||||
X509Certificate[] certificates = JVMHelper.getCertificates(clazz);
|
|
||||||
if (certificates == null) {
|
|
||||||
if (mode == LauncherTrustManager.CheckMode.EXCEPTION_IN_NOT_SIGNED)
|
|
||||||
throw new SecurityException(String.format("Class %s not signed", clazz.getName()));
|
|
||||||
else if (mode == LauncherTrustManager.CheckMode.WARN_IN_NOT_SIGNED)
|
|
||||||
logger.warn("Class {} not signed", clazz.getName());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
trustManager.checkCertificatesSuccess(certificates, trustManager::stdCertificateChecker);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new SecurityException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public LauncherTrustManager.CheckClassResult checkClass(Class<?> clazz) {
|
public LauncherTrustManager.CheckClassResult checkClass(Class<?> clazz) {
|
||||||
X509Certificate[] certificates = JVMHelper.getCertificates(clazz);
|
X509Certificate[] certificates = JVMHelper.getCertificates(clazz);
|
||||||
return trustManager.checkCertificates(certificates, trustManager::stdCertificateChecker);
|
return trustManager.checkCertificates(certificates, trustManager::stdCertificateChecker);
|
||||||
|
|
|
@ -11,15 +11,12 @@
|
||||||
import pro.gravit.launcher.request.auth.AuthRequest;
|
import pro.gravit.launcher.request.auth.AuthRequest;
|
||||||
import pro.gravit.launcher.request.auth.GetAvailabilityAuthRequest;
|
import pro.gravit.launcher.request.auth.GetAvailabilityAuthRequest;
|
||||||
import pro.gravit.launchserver.auth.core.AuthCoreProvider;
|
import pro.gravit.launchserver.auth.core.AuthCoreProvider;
|
||||||
import pro.gravit.launchserver.auth.handler.AuthHandler;
|
|
||||||
import pro.gravit.launchserver.auth.password.PasswordVerifier;
|
import pro.gravit.launchserver.auth.password.PasswordVerifier;
|
||||||
import pro.gravit.launchserver.auth.protect.ProtectHandler;
|
import pro.gravit.launchserver.auth.protect.ProtectHandler;
|
||||||
import pro.gravit.launchserver.auth.protect.hwid.HWIDProvider;
|
import pro.gravit.launchserver.auth.protect.hwid.HWIDProvider;
|
||||||
import pro.gravit.launchserver.auth.provider.AuthProvider;
|
|
||||||
import pro.gravit.launchserver.auth.session.SessionStorage;
|
import pro.gravit.launchserver.auth.session.SessionStorage;
|
||||||
import pro.gravit.launchserver.auth.texture.TextureProvider;
|
import pro.gravit.launchserver.auth.texture.TextureProvider;
|
||||||
import pro.gravit.launchserver.components.Component;
|
import pro.gravit.launchserver.components.Component;
|
||||||
import pro.gravit.launchserver.dao.provider.DaoProvider;
|
|
||||||
import pro.gravit.launchserver.modules.impl.LaunchServerModulesManager;
|
import pro.gravit.launchserver.modules.impl.LaunchServerModulesManager;
|
||||||
import pro.gravit.launchserver.socket.WebSocketService;
|
import pro.gravit.launchserver.socket.WebSocketService;
|
||||||
import pro.gravit.launchserver.socket.response.UnknownResponse;
|
import pro.gravit.launchserver.socket.response.UnknownResponse;
|
||||||
|
@ -34,17 +31,13 @@ public LaunchServerGsonManager(LaunchServerModulesManager modulesManager) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public void registerAdapters(GsonBuilder builder) {
|
public void registerAdapters(GsonBuilder builder) {
|
||||||
super.registerAdapters(builder);
|
super.registerAdapters(builder);
|
||||||
builder.registerTypeAdapter(AuthProvider.class, new UniversalJsonAdapter<>(AuthProvider.providers));
|
|
||||||
builder.registerTypeAdapter(TextureProvider.class, new UniversalJsonAdapter<>(TextureProvider.providers));
|
builder.registerTypeAdapter(TextureProvider.class, new UniversalJsonAdapter<>(TextureProvider.providers));
|
||||||
builder.registerTypeAdapter(AuthHandler.class, new UniversalJsonAdapter<>(AuthHandler.providers));
|
|
||||||
builder.registerTypeAdapter(AuthCoreProvider.class, new UniversalJsonAdapter<>(AuthCoreProvider.providers));
|
builder.registerTypeAdapter(AuthCoreProvider.class, new UniversalJsonAdapter<>(AuthCoreProvider.providers));
|
||||||
builder.registerTypeAdapter(PasswordVerifier.class, new UniversalJsonAdapter<>(PasswordVerifier.providers));
|
builder.registerTypeAdapter(PasswordVerifier.class, new UniversalJsonAdapter<>(PasswordVerifier.providers));
|
||||||
builder.registerTypeAdapter(Component.class, new UniversalJsonAdapter<>(Component.providers));
|
builder.registerTypeAdapter(Component.class, new UniversalJsonAdapter<>(Component.providers));
|
||||||
builder.registerTypeAdapter(ProtectHandler.class, new UniversalJsonAdapter<>(ProtectHandler.providers));
|
builder.registerTypeAdapter(ProtectHandler.class, new UniversalJsonAdapter<>(ProtectHandler.providers));
|
||||||
builder.registerTypeAdapter(DaoProvider.class, new UniversalJsonAdapter<>(DaoProvider.providers));
|
|
||||||
builder.registerTypeAdapter(WebSocketServerResponse.class, new UniversalJsonAdapter<>(WebSocketService.providers, UnknownResponse.class));
|
builder.registerTypeAdapter(WebSocketServerResponse.class, new UniversalJsonAdapter<>(WebSocketService.providers, UnknownResponse.class));
|
||||||
builder.registerTypeAdapter(WebSocketEvent.class, new JsonResultSerializeAdapter());
|
builder.registerTypeAdapter(WebSocketEvent.class, new JsonResultSerializeAdapter());
|
||||||
builder.registerTypeAdapter(AuthRequest.AuthPasswordInterface.class, new UniversalJsonAdapter<>(AuthRequest.providers));
|
builder.registerTypeAdapter(AuthRequest.AuthPasswordInterface.class, new UniversalJsonAdapter<>(AuthRequest.providers));
|
||||||
|
|
|
@ -3,12 +3,10 @@
|
||||||
import pro.gravit.launcher.Launcher;
|
import pro.gravit.launcher.Launcher;
|
||||||
import pro.gravit.launcher.NeedGarbageCollection;
|
import pro.gravit.launcher.NeedGarbageCollection;
|
||||||
import pro.gravit.launchserver.LaunchServer;
|
import pro.gravit.launchserver.LaunchServer;
|
||||||
import pro.gravit.launchserver.auth.RequiredDAO;
|
|
||||||
import pro.gravit.launchserver.socket.Client;
|
import pro.gravit.launchserver.socket.Client;
|
||||||
import pro.gravit.utils.HookSet;
|
import pro.gravit.utils.HookSet;
|
||||||
import pro.gravit.utils.helper.IOHelper;
|
import pro.gravit.utils.helper.IOHelper;
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
@ -36,11 +34,6 @@ public boolean removeByUUID(UUID uuid) {
|
||||||
return server.config.sessions.deleteSessionsByUserUUID(uuid);
|
return server.config.sessions.deleteSessionsByUserUUID(uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public Set<UUID> getSavedUUIDs() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clear() {
|
public void clear() {
|
||||||
server.config.sessions.clear();
|
server.config.sessions.clear();
|
||||||
}
|
}
|
||||||
|
@ -53,18 +46,11 @@ private Client decompressClient(byte[] client) {
|
||||||
return Launcher.gsonManager.gson.fromJson(IOHelper.decode(client), Client.class); //Compress using later
|
return Launcher.gsonManager.gson.fromJson(IOHelper.decode(client), Client.class); //Compress using later
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
private Client restoreFromString(byte[] data) {
|
private Client restoreFromString(byte[] data) {
|
||||||
Client result = decompressClient(data);
|
Client result = decompressClient(data);
|
||||||
result.updateAuth(server);
|
result.updateAuth(server);
|
||||||
if (result.auth != null && (result.username != null)) {
|
if (result.auth != null && (result.username != null)) {
|
||||||
if (result.auth.isUseCore()) {
|
|
||||||
result.coreObject = result.auth.core.getUserByUUID(result.uuid);
|
result.coreObject = result.auth.core.getUserByUUID(result.uuid);
|
||||||
} else {
|
|
||||||
if (result.auth.handler instanceof RequiredDAO || result.auth.provider instanceof RequiredDAO || result.auth.textureProvider instanceof RequiredDAO) {
|
|
||||||
result.daoObject = server.config.dao.userDAO.findByUsername(result.username);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (result.refCount == null) result.refCount = new AtomicInteger(1);
|
if (result.refCount == null) result.refCount = new AtomicInteger(1);
|
||||||
clientRestoreHook.hook(result);
|
clientRestoreHook.hook(result);
|
||||||
|
@ -92,25 +78,4 @@ public Client getOrNewClient(UUID session) {
|
||||||
public boolean remove(UUID session) {
|
public boolean remove(UUID session) {
|
||||||
return server.config.sessions.deleteSession(session);
|
return server.config.sessions.deleteSession(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public void removeClient(UUID session) {
|
|
||||||
remove(session);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public void updateClient(UUID session) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public Set<Client> getSessions() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public void loadSessions(Set<Client> set) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
//clientSet.putAll(set.stream().collect(Collectors.toMap(c -> c.session, Function.identity())));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,14 +2,10 @@
|
||||||
|
|
||||||
import pro.gravit.launcher.LauncherTrustManager;
|
import pro.gravit.launcher.LauncherTrustManager;
|
||||||
import pro.gravit.launcher.modules.LauncherModule;
|
import pro.gravit.launcher.modules.LauncherModule;
|
||||||
import pro.gravit.launcher.modules.LauncherModuleInfo;
|
|
||||||
import pro.gravit.launcher.modules.impl.SimpleModuleManager;
|
import pro.gravit.launcher.modules.impl.SimpleModuleManager;
|
||||||
import pro.gravit.launchserver.LaunchServer;
|
import pro.gravit.launchserver.LaunchServer;
|
||||||
import pro.gravit.utils.helper.LogHelper;
|
|
||||||
|
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.security.cert.X509Certificate;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -26,23 +22,6 @@ public void fullInitializedLaunchServer(LaunchServer server) {
|
||||||
initContext = new LaunchServerInitContext(server);
|
initContext = new LaunchServerInitContext(server);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public void printModulesInfo() {
|
|
||||||
for (LauncherModule module : modules) {
|
|
||||||
LauncherModuleInfo info = module.getModuleInfo();
|
|
||||||
LauncherTrustManager.CheckClassResult checkStatus = module.getCheckResult();
|
|
||||||
LogHelper.info("[MODULE] %s v: %s p: %d deps: %s sig: %s", info.name, info.version.getVersionString(), info.priority, Arrays.toString(info.dependencies), checkStatus == null ? "null" : checkStatus.type);
|
|
||||||
if (checkStatus != null && checkStatus.endCertificate != null) {
|
|
||||||
X509Certificate cert = checkStatus.endCertificate;
|
|
||||||
LogHelper.info("[MODULE CERT] Module signer: %s", cert.getSubjectDN().getName());
|
|
||||||
}
|
|
||||||
if (checkStatus != null && checkStatus.rootCertificate != null) {
|
|
||||||
X509Certificate cert = checkStatus.rootCertificate;
|
|
||||||
LogHelper.info("[MODULE CERT] Module signer CA: %s", cert.getSubjectDN().getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<LauncherModule> getModules() {
|
public List<LauncherModule> getModules() {
|
||||||
return Collections.unmodifiableList(modules);
|
return Collections.unmodifiableList(modules);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
import pro.gravit.launcher.request.secure.HardwareReportRequest;
|
import pro.gravit.launcher.request.secure.HardwareReportRequest;
|
||||||
import pro.gravit.launchserver.LaunchServer;
|
import pro.gravit.launchserver.LaunchServer;
|
||||||
import pro.gravit.launchserver.auth.AuthProviderPair;
|
import pro.gravit.launchserver.auth.AuthProviderPair;
|
||||||
import pro.gravit.launchserver.dao.User;
|
|
||||||
import pro.gravit.launchserver.socket.response.auth.AuthResponse;
|
import pro.gravit.launchserver.socket.response.auth.AuthResponse;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -29,9 +28,6 @@ public class Client {
|
||||||
|
|
||||||
public transient AuthProviderPair auth;
|
public transient AuthProviderPair auth;
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public transient User daoObject;
|
|
||||||
|
|
||||||
public transient pro.gravit.launchserver.auth.core.User coreObject;
|
public transient pro.gravit.launchserver.auth.core.User coreObject;
|
||||||
|
|
||||||
public transient pro.gravit.launchserver.auth.core.UserSession sessionObject;
|
public transient pro.gravit.launchserver.auth.core.UserSession sessionObject;
|
||||||
|
@ -86,18 +82,12 @@ public void setSerializableProperty(String name, String value) {
|
||||||
|
|
||||||
public pro.gravit.launchserver.auth.core.User getUser() {
|
public pro.gravit.launchserver.auth.core.User getUser() {
|
||||||
if (coreObject != null) return coreObject;
|
if (coreObject != null) return coreObject;
|
||||||
if (auth != null && uuid != null && auth.isUseCore()) {
|
if (auth != null && uuid != null) {
|
||||||
coreObject = auth.core.getUserByUUID(uuid);
|
coreObject = auth.core.getUserByUUID(uuid);
|
||||||
}
|
}
|
||||||
return coreObject;
|
return coreObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public enum Type {
|
|
||||||
SERVER,
|
|
||||||
USER
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class TrustLevel {
|
public static class TrustLevel {
|
||||||
public byte[] verifySecureKey;
|
public byte[] verifySecureKey;
|
||||||
public boolean keyChecked;
|
public boolean keyChecked;
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
import pro.gravit.launcher.events.request.ExitRequestEvent;
|
import pro.gravit.launcher.events.request.ExitRequestEvent;
|
||||||
import pro.gravit.launcher.request.WebSocketEvent;
|
import pro.gravit.launcher.request.WebSocketEvent;
|
||||||
import pro.gravit.launchserver.LaunchServer;
|
import pro.gravit.launchserver.LaunchServer;
|
||||||
import pro.gravit.launchserver.dao.User;
|
|
||||||
import pro.gravit.launchserver.socket.handlers.WebSocketFrameHandler;
|
import pro.gravit.launchserver.socket.handlers.WebSocketFrameHandler;
|
||||||
import pro.gravit.launchserver.socket.response.SimpleResponse;
|
import pro.gravit.launchserver.socket.response.SimpleResponse;
|
||||||
import pro.gravit.launchserver.socket.response.WebSocketServerResponse;
|
import pro.gravit.launchserver.socket.response.WebSocketServerResponse;
|
||||||
|
@ -43,7 +42,6 @@
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
public class WebSocketService {
|
public class WebSocketService {
|
||||||
public static final ProviderMap<WebSocketServerResponse> providers = new ProviderMap<>();
|
public static final ProviderMap<WebSocketServerResponse> providers = new ProviderMap<>();
|
||||||
|
@ -155,8 +153,7 @@ void process(ChannelHandlerContext ctx, WebSocketServerResponse response, Client
|
||||||
if (hook.hook(context, ctx)) {
|
if (hook.hook(context, ctx)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (response instanceof SimpleResponse) {
|
if (response instanceof SimpleResponse simpleResponse) {
|
||||||
SimpleResponse simpleResponse = (SimpleResponse) response;
|
|
||||||
simpleResponse.server = server;
|
simpleResponse.server = server;
|
||||||
simpleResponse.service = this;
|
simpleResponse.service = this;
|
||||||
simpleResponse.ctx = ctx;
|
simpleResponse.ctx = ctx;
|
||||||
|
@ -223,19 +220,6 @@ public void sendObjectToUUID(UUID userUuid, Object obj, Type type) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public void updateDaoObject(UUID userUuid, User daoObject, Consumer<Channel> callback) {
|
|
||||||
for (Channel ch : channels) {
|
|
||||||
if (ch == null || ch.pipeline() == null) continue;
|
|
||||||
WebSocketFrameHandler wsHandler = ch.pipeline().get(WebSocketFrameHandler.class);
|
|
||||||
if (wsHandler == null) continue;
|
|
||||||
Client client = wsHandler.getClient();
|
|
||||||
if (client == null || client.daoObject == null || !userUuid.equals(client.uuid)) continue;
|
|
||||||
client.daoObject = daoObject;
|
|
||||||
if (callback != null) callback.accept(ch);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Channel getChannelFromConnectUUID(UUID connectUuid) {
|
public Channel getChannelFromConnectUUID(UUID connectUuid) {
|
||||||
for (Channel ch : channels) {
|
for (Channel ch : channels) {
|
||||||
if (ch == null || ch.pipeline() == null) continue;
|
if (ch == null || ch.pipeline() == null) continue;
|
||||||
|
|
|
@ -13,8 +13,6 @@
|
||||||
public final class NettyServerSocketHandler implements Runnable, AutoCloseable {
|
public final class NettyServerSocketHandler implements Runnable, AutoCloseable {
|
||||||
private transient final LaunchServer server;
|
private transient final LaunchServer server;
|
||||||
private transient final Logger logger = LogManager.getLogger();
|
private transient final Logger logger = LogManager.getLogger();
|
||||||
@Deprecated
|
|
||||||
public volatile boolean logConnections = Boolean.getBoolean("launcher.logConnections");
|
|
||||||
public LauncherNettyServer nettyServer;
|
public LauncherNettyServer nettyServer;
|
||||||
private SSLServerSocketFactory ssf;
|
private SSLServerSocketFactory ssf;
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
public class AdditionalDataResponse extends SimpleResponse {
|
public class AdditionalDataResponse extends SimpleResponse {
|
||||||
public String username;
|
public String username;
|
||||||
public UUID uuid;
|
public UUID uuid;
|
||||||
|
@ -23,7 +24,7 @@ public String getType() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
|
public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
|
||||||
if (!client.isAuth || !client.auth.isUseCore()) {
|
if (!client.isAuth) {
|
||||||
sendError("Access denied");
|
sendError("Access denied");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -31,8 +32,7 @@ public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
|
||||||
if (username == null && uuid == null) {
|
if (username == null && uuid == null) {
|
||||||
Map<String, String> properties;
|
Map<String, String> properties;
|
||||||
User user = client.getUser();
|
User user = client.getUser();
|
||||||
if (user instanceof UserSupportAdditionalData) {
|
if (user instanceof UserSupportAdditionalData userSupport) {
|
||||||
UserSupportAdditionalData userSupport = (UserSupportAdditionalData) user;
|
|
||||||
if (user.getPermissions().isPermission(ClientPermissions.PermissionConsts.ADMIN)) {
|
if (user.getPermissions().isPermission(ClientPermissions.PermissionConsts.ADMIN)) {
|
||||||
properties = userSupport.getPropertiesMap();
|
properties = userSupport.getPropertiesMap();
|
||||||
} else {
|
} else {
|
||||||
|
@ -50,11 +50,10 @@ public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
|
||||||
} else {
|
} else {
|
||||||
user = pair.core.getUserByUUID(uuid);
|
user = pair.core.getUserByUUID(uuid);
|
||||||
}
|
}
|
||||||
if (!(user instanceof UserSupportAdditionalData)) {
|
if (!(user instanceof UserSupportAdditionalData userSupport)) {
|
||||||
sendResult(new AdditionalDataRequestEvent(Map.of()));
|
sendResult(new AdditionalDataRequestEvent(Map.of()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
UserSupportAdditionalData userSupport = (UserSupportAdditionalData) user;
|
|
||||||
Map<String, String> properties;
|
Map<String, String> properties;
|
||||||
if (client.permissions.isPermission(ClientPermissions.PermissionConsts.ADMIN)) {
|
if (client.permissions.isPermission(ClientPermissions.PermissionConsts.ADMIN)) {
|
||||||
properties = userSupport.getPropertiesMap();
|
properties = userSupport.getPropertiesMap();
|
||||||
|
|
|
@ -48,7 +48,7 @@ public void execute(ChannelHandlerContext ctx, Client clientData) throws Excepti
|
||||||
context.report = server.authManager.auth(context, password);
|
context.report = server.authManager.auth(context, password);
|
||||||
server.authHookManager.postHook.hook(context, clientData);
|
server.authHookManager.postHook.hook(context, clientData);
|
||||||
if (context.report.isUsingOAuth()) {
|
if (context.report.isUsingOAuth()) {
|
||||||
result.oauth = new AuthRequestEvent.OAuthRequestEvent(context.report.oauthAccessToken, context.report.oauthRefreshToken, context.report.oauthExpire);
|
result.oauth = new AuthRequestEvent.OAuthRequestEvent(context.report.oauthAccessToken(), context.report.oauthRefreshToken(), context.report.oauthExpire());
|
||||||
} else if (getSession) {
|
} else if (getSession) {
|
||||||
if (clientData.session == null) {
|
if (clientData.session == null) {
|
||||||
clientData.session = UUID.randomUUID();
|
clientData.session = UUID.randomUUID();
|
||||||
|
@ -56,8 +56,8 @@ public void execute(ChannelHandlerContext ctx, Client clientData) throws Excepti
|
||||||
}
|
}
|
||||||
result.session = clientData.session;
|
result.session = clientData.session;
|
||||||
}
|
}
|
||||||
if (context.report.minecraftAccessToken != null) {
|
if (context.report.minecraftAccessToken() != null) {
|
||||||
result.accessToken = context.report.minecraftAccessToken;
|
result.accessToken = context.report.minecraftAccessToken();
|
||||||
}
|
}
|
||||||
result.playerProfile = server.authManager.getPlayerProfile(clientData);
|
result.playerProfile = server.authManager.getPlayerProfile(clientData);
|
||||||
sendResult(result);
|
sendResult(result);
|
||||||
|
@ -67,8 +67,6 @@ public void execute(ChannelHandlerContext ctx, Client clientData) throws Excepti
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum ConnectTypes {
|
public enum ConnectTypes {
|
||||||
@Deprecated
|
|
||||||
SERVER,
|
|
||||||
CLIENT,
|
CLIENT,
|
||||||
API
|
API
|
||||||
}
|
}
|
||||||
|
@ -81,8 +79,6 @@ public static class AuthContext {
|
||||||
public final Client client;
|
public final Client client;
|
||||||
public final AuthProviderPair pair;
|
public final AuthProviderPair pair;
|
||||||
public AuthManager.AuthReport report;
|
public AuthManager.AuthReport report;
|
||||||
@Deprecated
|
|
||||||
public int password_length; //Use AuthProvider for get password
|
|
||||||
|
|
||||||
public AuthContext(Client client, String login, String profileName, String ip, ConnectTypes authType, AuthProviderPair pair) {
|
public AuthContext(Client client, String login, String profileName, String ip, ConnectTypes authType, AuthProviderPair pair) {
|
||||||
this.client = client;
|
this.client = client;
|
||||||
|
|
|
@ -23,7 +23,7 @@ public String getType() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(ChannelHandlerContext ctx, Client pClient) {
|
public void execute(ChannelHandlerContext ctx, Client pClient) {
|
||||||
if (!pClient.isAuth || pClient.type == AuthResponse.ConnectTypes.CLIENT) {
|
if (pClient.permissions == null || !pClient.permissions.hasPerm("launchserver.checkserver")) {
|
||||||
sendError("Permissions denied");
|
sendError("Permissions denied");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -46,5 +46,4 @@ public void execute(ChannelHandlerContext ctx, Client pClient) {
|
||||||
}
|
}
|
||||||
sendResult(result);
|
sendResult(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,24 +5,10 @@
|
||||||
import pro.gravit.launchserver.LaunchServer;
|
import pro.gravit.launchserver.LaunchServer;
|
||||||
import pro.gravit.launchserver.socket.Client;
|
import pro.gravit.launchserver.socket.Client;
|
||||||
import pro.gravit.launchserver.socket.response.SimpleResponse;
|
import pro.gravit.launchserver.socket.response.SimpleResponse;
|
||||||
import pro.gravit.launchserver.socket.response.profile.ProfileByUUIDResponse;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class CurrentUserResponse extends SimpleResponse {
|
public class CurrentUserResponse extends SimpleResponse {
|
||||||
@Deprecated
|
|
||||||
public static CurrentUserRequestEvent.UserInfo collectUserInfoFromClient(Client client) throws IOException {
|
|
||||||
CurrentUserRequestEvent.UserInfo result = new CurrentUserRequestEvent.UserInfo();
|
|
||||||
if (client.auth != null && client.isAuth && client.username != null) {
|
|
||||||
UUID uuid = client.uuid != null ? client.uuid : client.auth.handler.usernameToUUID(client.username);
|
|
||||||
if (uuid != null) {
|
|
||||||
result.playerProfile = ProfileByUUIDResponse.getProfile(uuid, client.username, client.profile == null ? null : client.profile.getTitle(), client.auth.textureProvider);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result.permissions = client.permissions;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static CurrentUserRequestEvent.UserInfo collectUserInfoFromClient(LaunchServer server, Client client) throws IOException {
|
public static CurrentUserRequestEvent.UserInfo collectUserInfoFromClient(LaunchServer server, Client client) throws IOException {
|
||||||
CurrentUserRequestEvent.UserInfo result = new CurrentUserRequestEvent.UserInfo();
|
CurrentUserRequestEvent.UserInfo result = new CurrentUserRequestEvent.UserInfo();
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
import io.netty.channel.Channel;
|
import io.netty.channel.Channel;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import pro.gravit.launcher.ClientPermissions;
|
|
||||||
import pro.gravit.launcher.events.RequestEvent;
|
import pro.gravit.launcher.events.RequestEvent;
|
||||||
import pro.gravit.launcher.events.request.ExitRequestEvent;
|
import pro.gravit.launcher.events.request.ExitRequestEvent;
|
||||||
import pro.gravit.launchserver.LaunchServer;
|
import pro.gravit.launchserver.LaunchServer;
|
||||||
|
@ -35,7 +34,7 @@ public String getType() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(ChannelHandlerContext ctx, Client client) {
|
public void execute(ChannelHandlerContext ctx, Client client) {
|
||||||
if (username != null && (!client.isAuth || client.permissions == null || !client.permissions.isPermission(ClientPermissions.PermissionConsts.ADMIN))) {
|
if (username != null && (!client.isAuth || client.permissions == null || !client.permissions.hasPerm("launchserver\\.management\\.kick"))) {
|
||||||
sendError("Permissions denied");
|
sendError("Permissions denied");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,8 @@ public String getType() {
|
||||||
public void execute(ChannelHandlerContext ctx, Client client) {
|
public void execute(ChannelHandlerContext ctx, Client client) {
|
||||||
List<GetAvailabilityAuthRequestEvent.AuthAvailability> list = new ArrayList<>();
|
List<GetAvailabilityAuthRequestEvent.AuthAvailability> list = new ArrayList<>();
|
||||||
for (AuthProviderPair pair : server.config.auth.values()) {
|
for (AuthProviderPair pair : server.config.auth.values()) {
|
||||||
list.add(new GetAvailabilityAuthRequestEvent.AuthAvailability(pair.name, pair.displayName, pair.isUseCore() ? (pair.isUseSocial() ? pair.social.getDetails(client) : pair.core.getDetails(client)) : pair.provider.getDetails(client)));
|
list.add(new GetAvailabilityAuthRequestEvent.AuthAvailability(pair.name, pair.displayName,
|
||||||
|
pair.isUseSocial() ? pair.social.getDetails(client) : pair.core.getDetails(client)));
|
||||||
}
|
}
|
||||||
sendResult(new GetAvailabilityAuthRequestEvent(list));
|
sendResult(new GetAvailabilityAuthRequestEvent(list));
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,8 +26,7 @@ public void execute(ChannelHandlerContext ctx, Client client) {
|
||||||
|
|
||||||
List<ClientProfile> profileList;
|
List<ClientProfile> profileList;
|
||||||
Set<ClientProfile> serverProfiles = server.getProfiles();
|
Set<ClientProfile> serverProfiles = server.getProfiles();
|
||||||
if (server.config.protectHandler instanceof ProfilesProtectHandler) {
|
if (server.config.protectHandler instanceof ProfilesProtectHandler protectHandler) {
|
||||||
ProfilesProtectHandler protectHandler = (ProfilesProtectHandler) server.config.protectHandler;
|
|
||||||
profileList = new ArrayList<>(4);
|
profileList = new ArrayList<>(4);
|
||||||
for (ClientProfile profile : serverProfiles) {
|
for (ClientProfile profile : serverProfiles) {
|
||||||
if (protectHandler.canGetProfile(profile, client)) {
|
if (protectHandler.canGetProfile(profile, client)) {
|
||||||
|
|
|
@ -33,7 +33,7 @@ public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
|
||||||
} else {
|
} else {
|
||||||
pair = client.auth;
|
pair = client.auth;
|
||||||
}
|
}
|
||||||
if (pair == null || !pair.isUseCore()) {
|
if (pair == null) {
|
||||||
sendError("Invalid request");
|
sendError("Invalid request");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,6 @@ public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
|
||||||
sendError("Invalid RefreshToken");
|
sendError("Invalid RefreshToken");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
sendResult(new RefreshTokenRequestEvent(new AuthRequestEvent.OAuthRequestEvent(report.oauthAccessToken, report.oauthRefreshToken, report.oauthExpire)));
|
sendResult(new RefreshTokenRequestEvent(new AuthRequestEvent.OAuthRequestEvent(report.oauthAccessToken(), report.oauthRefreshToken(), report.oauthExpire())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
import pro.gravit.launchserver.auth.core.User;
|
import pro.gravit.launchserver.auth.core.User;
|
||||||
import pro.gravit.launchserver.auth.core.UserSession;
|
import pro.gravit.launchserver.auth.core.UserSession;
|
||||||
import pro.gravit.launchserver.auth.protect.AdvancedProtectHandler;
|
import pro.gravit.launchserver.auth.protect.AdvancedProtectHandler;
|
||||||
|
import pro.gravit.launchserver.manangers.AuthManager;
|
||||||
import pro.gravit.launchserver.socket.Client;
|
import pro.gravit.launchserver.socket.Client;
|
||||||
import pro.gravit.launchserver.socket.response.SimpleResponse;
|
import pro.gravit.launchserver.socket.response.SimpleResponse;
|
||||||
import pro.gravit.launchserver.socket.response.update.LauncherResponse;
|
import pro.gravit.launchserver.socket.response.update.LauncherResponse;
|
||||||
|
@ -32,6 +33,7 @@ public static void registerProviders(LaunchServer server) {
|
||||||
providers.put(LauncherRequestEvent.LAUNCHER_EXTENDED_TOKEN_NAME, new LauncherResponse.LauncherTokenVerifier(server));
|
providers.put(LauncherRequestEvent.LAUNCHER_EXTENDED_TOKEN_NAME, new LauncherResponse.LauncherTokenVerifier(server));
|
||||||
providers.put("publicKey", new AdvancedProtectHandler.PublicKeyTokenVerifier(server));
|
providers.put("publicKey", new AdvancedProtectHandler.PublicKeyTokenVerifier(server));
|
||||||
providers.put("hardware", new AdvancedProtectHandler.HardwareInfoTokenVerifier(server));
|
providers.put("hardware", new AdvancedProtectHandler.HardwareInfoTokenVerifier(server));
|
||||||
|
providers.put("checkServer", new AuthManager.CheckServerVerifier(server));
|
||||||
registeredProviders = true;
|
registeredProviders = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,7 +59,7 @@ public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
|
||||||
} else {
|
} else {
|
||||||
pair = client.auth;
|
pair = client.auth;
|
||||||
}
|
}
|
||||||
if (pair == null || !pair.isUseCore()) {
|
if (pair == null) {
|
||||||
sendError("Invalid authId");
|
sendError("Invalid authId");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package pro.gravit.launchserver.socket.response.management;
|
package pro.gravit.launchserver.socket.response.management;
|
||||||
|
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import pro.gravit.launcher.ClientPermissions;
|
|
||||||
import pro.gravit.launcher.events.request.PingServerReportRequestEvent;
|
import pro.gravit.launcher.events.request.PingServerReportRequestEvent;
|
||||||
import pro.gravit.launcher.request.management.PingServerReportRequest;
|
import pro.gravit.launcher.request.management.PingServerReportRequest;
|
||||||
import pro.gravit.launchserver.socket.Client;
|
import pro.gravit.launchserver.socket.Client;
|
||||||
|
@ -18,7 +17,7 @@ public String getType() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(ChannelHandlerContext ctx, Client client) {
|
public void execute(ChannelHandlerContext ctx, Client client) {
|
||||||
if (!client.isAuth || client.permissions == null || !client.permissions.isPermission(ClientPermissions.PermissionConsts.MANAGEMENT)) {
|
if (!client.isAuth || client.permissions == null || !client.permissions.hasPerm("launchserver\\.management\\.pingserver")) {
|
||||||
sendError("Access denied");
|
sendError("Access denied");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,43 +2,17 @@
|
||||||
|
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import pro.gravit.launcher.events.request.ProfileByUUIDRequestEvent;
|
import pro.gravit.launcher.events.request.ProfileByUUIDRequestEvent;
|
||||||
import pro.gravit.launcher.profiles.PlayerProfile;
|
|
||||||
import pro.gravit.launcher.profiles.Texture;
|
|
||||||
import pro.gravit.launchserver.auth.AuthProviderPair;
|
import pro.gravit.launchserver.auth.AuthProviderPair;
|
||||||
import pro.gravit.launchserver.auth.core.User;
|
import pro.gravit.launchserver.auth.core.User;
|
||||||
import pro.gravit.launchserver.auth.texture.TextureProvider;
|
|
||||||
import pro.gravit.launchserver.socket.Client;
|
import pro.gravit.launchserver.socket.Client;
|
||||||
import pro.gravit.launchserver.socket.response.SimpleResponse;
|
import pro.gravit.launchserver.socket.response.SimpleResponse;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public class ProfileByUUIDResponse extends SimpleResponse {
|
public class ProfileByUUIDResponse extends SimpleResponse {
|
||||||
public UUID uuid;
|
public UUID uuid;
|
||||||
public String client;
|
public String client;
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public static PlayerProfile getProfile(UUID uuid, String username, String client, TextureProvider textureProvider) {
|
|
||||||
// Get skin texture
|
|
||||||
Texture skin;
|
|
||||||
try {
|
|
||||||
skin = textureProvider.getSkinTexture(uuid, username, client);
|
|
||||||
} catch (IOException e) {
|
|
||||||
skin = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get cloak texture
|
|
||||||
Texture cloak;
|
|
||||||
try {
|
|
||||||
cloak = textureProvider.getCloakTexture(uuid, username, client);
|
|
||||||
} catch (IOException e) {
|
|
||||||
cloak = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return combined profile
|
|
||||||
return new PlayerProfile(uuid, username, skin, cloak);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getType() {
|
public String getType() {
|
||||||
return "profileByUUID";
|
return "profileByUUID";
|
||||||
|
@ -46,7 +20,6 @@ public String getType() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
|
public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
|
||||||
String username;
|
|
||||||
AuthProviderPair pair;
|
AuthProviderPair pair;
|
||||||
if (client.auth == null) {
|
if (client.auth == null) {
|
||||||
pair = server.config.getAuthProviderPair();
|
pair = server.config.getAuthProviderPair();
|
||||||
|
@ -57,18 +30,10 @@ public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
|
||||||
sendError("ProfileByUUIDResponse: AuthProviderPair is null");
|
sendError("ProfileByUUIDResponse: AuthProviderPair is null");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (pair.isUseCore()) {
|
|
||||||
User user = pair.core.getUserByUUID(uuid);
|
User user = pair.core.getUserByUUID(uuid);
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
sendError("User not found");
|
sendError("User not found");
|
||||||
return;
|
return;
|
||||||
} else username = user.getUsername();
|
|
||||||
} else {
|
|
||||||
username = pair.handler.uuidToUsername(uuid);
|
|
||||||
if (username == null) {
|
|
||||||
sendError(String.format("ProfileByUUIDResponse: User with uuid %s not found or AuthProvider#uuidToUsername returned null", uuid));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
sendResult(new ProfileByUUIDRequestEvent(server.authManager.getPlayerProfile(pair, uuid)));
|
sendResult(new ProfileByUUIDRequestEvent(server.authManager.getPlayerProfile(pair, uuid)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,13 +14,12 @@ public String getType() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(ChannelHandlerContext ctx, Client client) {
|
public void execute(ChannelHandlerContext ctx, Client client) {
|
||||||
if (!(server.config.protectHandler instanceof SecureProtectHandler)) {
|
if (!(server.config.protectHandler instanceof SecureProtectHandler secureProtectHandler)) {
|
||||||
GetSecureLevelInfoRequestEvent response = new GetSecureLevelInfoRequestEvent(null);
|
GetSecureLevelInfoRequestEvent response = new GetSecureLevelInfoRequestEvent(null);
|
||||||
response.enabled = false;
|
response.enabled = false;
|
||||||
sendResult(response);
|
sendResult(response);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SecureProtectHandler secureProtectHandler = (SecureProtectHandler) server.config.protectHandler;
|
|
||||||
if (!secureProtectHandler.allowGetSecureLevelInfo(client)) {
|
if (!secureProtectHandler.allowGetSecureLevelInfo(client)) {
|
||||||
sendError("Access denied");
|
sendError("Access denied");
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -19,11 +19,10 @@ public String getType() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(ChannelHandlerContext ctx, Client client) {
|
public void execute(ChannelHandlerContext ctx, Client client) {
|
||||||
if (!(server.config.protectHandler instanceof SecureProtectHandler) || client.trustLevel == null || client.trustLevel.verifySecureKey == null) {
|
if (!(server.config.protectHandler instanceof SecureProtectHandler secureProtectHandler) || client.trustLevel == null || client.trustLevel.verifySecureKey == null) {
|
||||||
sendError("This method not allowed");
|
sendError("This method not allowed");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SecureProtectHandler secureProtectHandler = (SecureProtectHandler) server.config.protectHandler;
|
|
||||||
try {
|
try {
|
||||||
secureProtectHandler.verifySecureLevelKey(publicKey, client.trustLevel.verifySecureKey, signature);
|
secureProtectHandler.verifySecureLevelKey(publicKey, client.trustLevel.verifySecureKey, signature);
|
||||||
} catch (InvalidKeySpecException e) {
|
} catch (InvalidKeySpecException e) {
|
||||||
|
|
|
@ -2,18 +2,8 @@
|
||||||
|
|
||||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||||
import org.junit.jupiter.api.BeforeAll;
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.junit.jupiter.api.io.TempDir;
|
import org.junit.jupiter.api.io.TempDir;
|
||||||
import pro.gravit.launcher.ClientPermissions;
|
|
||||||
import pro.gravit.launcher.Launcher;
|
import pro.gravit.launcher.Launcher;
|
||||||
import pro.gravit.launcher.request.auth.AuthRequest;
|
|
||||||
import pro.gravit.launcher.request.auth.password.AuthPlainPassword;
|
|
||||||
import pro.gravit.launchserver.auth.AuthException;
|
|
||||||
import pro.gravit.launchserver.auth.AuthProviderPair;
|
|
||||||
import pro.gravit.launchserver.auth.handler.MemoryAuthHandler;
|
|
||||||
import pro.gravit.launchserver.auth.provider.AuthProvider;
|
|
||||||
import pro.gravit.launchserver.auth.provider.AuthProviderResult;
|
|
||||||
import pro.gravit.launchserver.auth.texture.NullTextureProvider;
|
|
||||||
import pro.gravit.launchserver.config.LaunchServerConfig;
|
import pro.gravit.launchserver.config.LaunchServerConfig;
|
||||||
import pro.gravit.launchserver.config.LaunchServerRuntimeConfig;
|
import pro.gravit.launchserver.config.LaunchServerRuntimeConfig;
|
||||||
import pro.gravit.launchserver.impl.TestLaunchServerConfigManager;
|
import pro.gravit.launchserver.impl.TestLaunchServerConfigManager;
|
||||||
|
@ -21,9 +11,7 @@
|
||||||
import pro.gravit.launchserver.manangers.LaunchServerGsonManager;
|
import pro.gravit.launchserver.manangers.LaunchServerGsonManager;
|
||||||
import pro.gravit.launchserver.modules.impl.LaunchServerModulesManager;
|
import pro.gravit.launchserver.modules.impl.LaunchServerModulesManager;
|
||||||
import pro.gravit.utils.command.StdCommandHandler;
|
import pro.gravit.utils.command.StdCommandHandler;
|
||||||
import pro.gravit.utils.helper.SecurityHelper;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.security.Security;
|
import java.security.Security;
|
||||||
|
|
||||||
|
@ -57,26 +45,4 @@ public static void prepare() throws Throwable {
|
||||||
.setCommandHandler(new StdCommandHandler(false));
|
.setCommandHandler(new StdCommandHandler(false));
|
||||||
launchServer = builder.build();
|
launchServer = builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void reloadTest() throws Exception {
|
|
||||||
AuthProvider provider = new AuthProvider() {
|
|
||||||
@Override
|
|
||||||
public AuthProviderResult auth(String login, AuthRequest.AuthPasswordInterface password, String ip) throws Exception {
|
|
||||||
if (!(password instanceof AuthPlainPassword)) throw new UnsupportedOperationException();
|
|
||||||
if (login.equals("test") && ((AuthPlainPassword) password).password.equals("test")) {
|
|
||||||
return new AuthProviderResult(login, SecurityHelper.randomStringToken(), new ClientPermissions());
|
|
||||||
}
|
|
||||||
throw new AuthException("Incorrect password");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() throws IOException {
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
|
||||||
AuthProviderPair pair = new AuthProviderPair(provider, new MemoryAuthHandler(), new NullTextureProvider());
|
|
||||||
launchServerConfigManager.config.auth.put("std", pair);
|
|
||||||
launchServer.reload(LaunchServer.ReloadType.FULL);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ public class AuthService {
|
||||||
public static UUID uuid;
|
public static UUID uuid;
|
||||||
public static ClientProfile profile;
|
public static ClientProfile profile;
|
||||||
|
|
||||||
public static boolean isAdmin() {
|
public static boolean hasPermission(String permission) {
|
||||||
return permissions.isPermission(ClientPermissions.PermissionConsts.ADMIN);
|
return permissions.hasPerm(permission);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,6 +163,9 @@ private Result modernPing(HInput input, HOutput output) throws IOException {
|
||||||
|
|
||||||
// Parse JSON response
|
// Parse JSON response
|
||||||
JsonObject object = JsonParser.parseString(response).getAsJsonObject();
|
JsonObject object = JsonParser.parseString(response).getAsJsonObject();
|
||||||
|
if(object.has("error")) {
|
||||||
|
throw new IOException(object.get("error").getAsString());
|
||||||
|
}
|
||||||
JsonObject playersObject = object.get("players").getAsJsonObject();
|
JsonObject playersObject = object.get("players").getAsJsonObject();
|
||||||
int online = playersObject.get("online").getAsInt();
|
int online = playersObject.get("online").getAsInt();
|
||||||
int max = playersObject.get("max").getAsInt();
|
int max = playersObject.get("max").getAsInt();
|
||||||
|
|
|
@ -1,16 +1,24 @@
|
||||||
package pro.gravit.launcher;
|
package pro.gravit.launcher;
|
||||||
|
|
||||||
import pro.gravit.launcher.serialize.HInput;
|
import pro.gravit.launcher.serialize.HInput;
|
||||||
import pro.gravit.launcher.serialize.HOutput;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
public class ClientPermissions {
|
public class ClientPermissions {
|
||||||
public static final ClientPermissions DEFAULT = new ClientPermissions();
|
public static final ClientPermissions DEFAULT = new ClientPermissions();
|
||||||
@LauncherNetworkAPI
|
@LauncherNetworkAPI
|
||||||
|
@Deprecated
|
||||||
public long permissions;
|
public long permissions;
|
||||||
@LauncherNetworkAPI
|
@LauncherNetworkAPI
|
||||||
|
@Deprecated
|
||||||
public long flags;
|
public long flags;
|
||||||
|
@LauncherNetworkAPI
|
||||||
|
private List<String> roles;
|
||||||
|
@LauncherNetworkAPI
|
||||||
|
private List<String> perms;
|
||||||
|
|
||||||
|
private transient List<PermissionPattern> available;
|
||||||
|
|
||||||
public ClientPermissions(HInput input) throws IOException {
|
public ClientPermissions(HInput input) throws IOException {
|
||||||
this(input.readLong());
|
this(input.readLong());
|
||||||
|
@ -32,6 +40,7 @@ public ClientPermissions(long permissions, long flags) {
|
||||||
public static ClientPermissions getSuperuserAccount() {
|
public static ClientPermissions getSuperuserAccount() {
|
||||||
ClientPermissions perm = new ClientPermissions();
|
ClientPermissions perm = new ClientPermissions();
|
||||||
perm.setPermission(PermissionConsts.ADMIN, true);
|
perm.setPermission(PermissionConsts.ADMIN, true);
|
||||||
|
perm.addPerm("*");
|
||||||
return perm;
|
return perm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,44 +48,116 @@ public long toLong() {
|
||||||
return permissions;
|
return permissions;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
public boolean hasRole(String role) {
|
||||||
public void write(HOutput output) throws IOException {
|
return roles != null && roles.contains(role);
|
||||||
output.writeLong(toLong());
|
}
|
||||||
|
|
||||||
|
public synchronized void compile() {
|
||||||
|
if (available != null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
available = new ArrayList<>(perms.size());
|
||||||
|
for (String a : perms) {
|
||||||
|
available.add(new PermissionPattern(a));
|
||||||
|
}
|
||||||
|
if (permissions != 0) {
|
||||||
|
if (isPermission(PermissionConsts.ADMIN)) {
|
||||||
|
roles.add("ADMIN");
|
||||||
|
available.add(new PermissionPattern("*"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasPerm(String action) {
|
||||||
|
if (available == null) {
|
||||||
|
compile();
|
||||||
|
}
|
||||||
|
for (PermissionPattern p : available) {
|
||||||
|
if (p.match(action)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addRole(String role) {
|
||||||
|
if (roles == null) {
|
||||||
|
roles = new ArrayList<>(1);
|
||||||
|
}
|
||||||
|
roles.add(role);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addPerm(String perm) {
|
||||||
|
if (perms == null) {
|
||||||
|
perms = new ArrayList<>(1);
|
||||||
|
}
|
||||||
|
perms.add(perm);
|
||||||
|
if(available == null) {
|
||||||
|
available = new ArrayList<>(1);
|
||||||
|
}
|
||||||
|
available.add(new PermissionPattern(perm));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removePerm(String action) {
|
||||||
|
if (perms == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(available == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
perms.remove(action);
|
||||||
|
available.remove(new PermissionPattern(action));
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getRoles() {
|
||||||
|
return roles;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getPerms() {
|
||||||
|
return perms;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Read methods
|
//Read methods
|
||||||
|
@Deprecated
|
||||||
public final boolean isPermission(PermissionConsts con) {
|
public final boolean isPermission(PermissionConsts con) {
|
||||||
return (permissions & con.mask) != 0;
|
return (permissions & con.mask) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final boolean isPermission(long mask) {
|
public final boolean isPermission(long mask) {
|
||||||
return (permissions & mask) != 0;
|
return (permissions & mask) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final boolean isFlag(FlagConsts con) {
|
public final boolean isFlag(FlagConsts con) {
|
||||||
return (flags & con.mask) != 0;
|
return (flags & con.mask) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final boolean isFlag(long mask) {
|
public final boolean isFlag(long mask) {
|
||||||
return (flags & mask) != 0;
|
return (flags & mask) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Write methods
|
//Write methods
|
||||||
|
@Deprecated
|
||||||
public final void setPermission(PermissionConsts con, boolean value) {
|
public final void setPermission(PermissionConsts con, boolean value) {
|
||||||
if (value) this.permissions |= con.mask;
|
if (value) this.permissions |= con.mask;
|
||||||
else this.permissions &= ~con.mask;
|
else this.permissions &= ~con.mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final void setPermission(long mask, boolean value) {
|
public final void setPermission(long mask, boolean value) {
|
||||||
if (value) this.permissions |= mask;
|
if (value) this.permissions |= mask;
|
||||||
else this.permissions &= ~mask;
|
else this.permissions &= ~mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final void setFlag(FlagConsts con, boolean value) {
|
public final void setFlag(FlagConsts con, boolean value) {
|
||||||
if (value) this.flags |= con.mask;
|
if (value) this.flags |= con.mask;
|
||||||
else this.flags &= ~con.mask;
|
else this.flags &= ~con.mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final void setFlag(long mask, boolean value) {
|
public final void setFlag(long mask, boolean value) {
|
||||||
if (value) this.flags |= mask;
|
if (value) this.flags |= mask;
|
||||||
else this.flags &= ~mask;
|
else this.flags &= ~mask;
|
||||||
|
@ -85,11 +166,12 @@ public final void setFlag(long mask, boolean value) {
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "ClientPermissions{" +
|
return "ClientPermissions{" +
|
||||||
"permissions=" + permissions +
|
"roles=" + String.join(", ", roles == null ? Collections.emptyList() : roles) +
|
||||||
", flags=" + flags +
|
", actions=" + String.join(", ", perms == null ? Collections.emptyList() : perms) +
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public enum PermissionConsts {
|
public enum PermissionConsts {
|
||||||
ADMIN(0x01),
|
ADMIN(0x01),
|
||||||
MANAGEMENT(0x02);
|
MANAGEMENT(0x02);
|
||||||
|
@ -100,7 +182,7 @@ public enum PermissionConsts {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public enum FlagConsts {
|
public enum FlagConsts {
|
||||||
SYSTEM(0x01),
|
SYSTEM(0x01),
|
||||||
BANNED(0x02),
|
BANNED(0x02),
|
||||||
|
@ -112,4 +194,69 @@ public enum FlagConsts {
|
||||||
this.mask = mask;
|
this.mask = mask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class PermissionPattern {
|
||||||
|
private final String[] parts;
|
||||||
|
private final int priority;
|
||||||
|
|
||||||
|
public PermissionPattern(String pattern) {
|
||||||
|
List<String> prepare = new ArrayList<>();
|
||||||
|
for(int i=0;true;) {
|
||||||
|
int pos = pattern.indexOf("*", i);
|
||||||
|
if(pos >= 0) {
|
||||||
|
prepare.add(pattern.substring(i, pos));
|
||||||
|
i = pos+1;
|
||||||
|
} else {
|
||||||
|
prepare.add(pattern.substring(i));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
priority = prepare.size() - 1;
|
||||||
|
parts = prepare.toArray(new String[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPriority() {
|
||||||
|
return priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean match(String str) {
|
||||||
|
if(parts.length == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(parts.length == 1) {
|
||||||
|
return parts[0].equals(str);
|
||||||
|
}
|
||||||
|
int offset = 0;
|
||||||
|
if(!str.startsWith(parts[0])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(!str.endsWith(parts[parts.length-1])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for(int i=1;i<parts.length-1;++i) {
|
||||||
|
int pos = str.indexOf(parts[i], offset);
|
||||||
|
if(pos >= 0) {
|
||||||
|
offset = pos+1;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
PermissionPattern that = (PermissionPattern) o;
|
||||||
|
return priority == that.priority && Arrays.equals(parts, that.parts);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = Objects.hash(priority);
|
||||||
|
result = 31 * result + Arrays.hashCode(parts);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,8 +32,6 @@ public final class LauncherConfig extends StreamObject {
|
||||||
public final ECPublicKey ecdsaPublicKey;
|
public final ECPublicKey ecdsaPublicKey;
|
||||||
public final RSAPublicKey rsaPublicKey;
|
public final RSAPublicKey rsaPublicKey;
|
||||||
public final Map<String, byte[]> runtime;
|
public final Map<String, byte[]> runtime;
|
||||||
@Deprecated
|
|
||||||
public final boolean isWarningMissArchJava;
|
|
||||||
@LauncherInject("launcher.guardType")
|
@LauncherInject("launcher.guardType")
|
||||||
public final String guardType;
|
public final String guardType;
|
||||||
@LauncherInject("runtimeconfig.secureCheckHash")
|
@LauncherInject("runtimeconfig.secureCheckHash")
|
||||||
|
@ -46,8 +44,6 @@ public final class LauncherConfig extends StreamObject {
|
||||||
public final String runtimeEncryptKey;
|
public final String runtimeEncryptKey;
|
||||||
@LauncherInject("launcher.address")
|
@LauncherInject("launcher.address")
|
||||||
public final String address;
|
public final String address;
|
||||||
@Deprecated
|
|
||||||
public ECPublicKey publicKey = null;
|
|
||||||
@LauncherInject("runtimeconfig.secretKeyClient")
|
@LauncherInject("runtimeconfig.secretKeyClient")
|
||||||
public String secretKeyClient;
|
public String secretKeyClient;
|
||||||
@LauncherInject("runtimeconfig.oemUnlockKey")
|
@LauncherInject("runtimeconfig.oemUnlockKey")
|
||||||
|
@ -60,7 +56,6 @@ public final class LauncherConfig extends StreamObject {
|
||||||
public LauncherConfig(HInput input) throws IOException, InvalidKeySpecException {
|
public LauncherConfig(HInput input) throws IOException, InvalidKeySpecException {
|
||||||
ecdsaPublicKey = SecurityHelper.toPublicECDSAKey(input.readByteArray(SecurityHelper.CRYPTO_MAX_LENGTH));
|
ecdsaPublicKey = SecurityHelper.toPublicECDSAKey(input.readByteArray(SecurityHelper.CRYPTO_MAX_LENGTH));
|
||||||
rsaPublicKey = SecurityHelper.toPublicRSAKey(input.readByteArray(SecurityHelper.CRYPTO_MAX_LENGTH));
|
rsaPublicKey = SecurityHelper.toPublicRSAKey(input.readByteArray(SecurityHelper.CRYPTO_MAX_LENGTH));
|
||||||
publicKey = ecdsaPublicKey;
|
|
||||||
secureCheckHash = null;
|
secureCheckHash = null;
|
||||||
secureCheckSalt = null;
|
secureCheckSalt = null;
|
||||||
passwordEncryptKey = null;
|
passwordEncryptKey = null;
|
||||||
|
@ -74,8 +69,6 @@ public LauncherConfig(HInput input) throws IOException, InvalidKeySpecException
|
||||||
} catch (CertificateException e) {
|
} catch (CertificateException e) {
|
||||||
throw new IOException(e);
|
throw new IOException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
isWarningMissArchJava = false;
|
|
||||||
guardType = null;
|
guardType = null;
|
||||||
address = null;
|
address = null;
|
||||||
environment = LauncherEnvironment.STD;
|
environment = LauncherEnvironment.STD;
|
||||||
|
@ -92,25 +85,6 @@ public LauncherConfig(HInput input) throws IOException, InvalidKeySpecException
|
||||||
runtime = Collections.unmodifiableMap(localResources);
|
runtime = Collections.unmodifiableMap(localResources);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public LauncherConfig(String address, ECPublicKey publicKey, Map<String, byte[]> runtime, String projectName) {
|
|
||||||
this.address = address;
|
|
||||||
this.publicKey = publicKey;
|
|
||||||
this.ecdsaPublicKey = this.publicKey;
|
|
||||||
this.rsaPublicKey = null;
|
|
||||||
this.runtime = Collections.unmodifiableMap(new HashMap<>(runtime));
|
|
||||||
this.projectName = projectName;
|
|
||||||
this.clientPort = 32148;
|
|
||||||
guardType = "no";
|
|
||||||
isWarningMissArchJava = true;
|
|
||||||
environment = LauncherEnvironment.STD;
|
|
||||||
secureCheckSalt = null;
|
|
||||||
secureCheckHash = null;
|
|
||||||
passwordEncryptKey = null;
|
|
||||||
runtimeEncryptKey = null;
|
|
||||||
trustManager = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LauncherConfig(String address, ECPublicKey ecdsaPublicKey, RSAPublicKey rsaPublicKey, Map<String, byte[]> runtime, String projectName) {
|
public LauncherConfig(String address, ECPublicKey ecdsaPublicKey, RSAPublicKey rsaPublicKey, Map<String, byte[]> runtime, String projectName) {
|
||||||
this.address = address;
|
this.address = address;
|
||||||
this.ecdsaPublicKey = ecdsaPublicKey;
|
this.ecdsaPublicKey = ecdsaPublicKey;
|
||||||
|
@ -119,7 +93,6 @@ public LauncherConfig(String address, ECPublicKey ecdsaPublicKey, RSAPublicKey r
|
||||||
this.projectName = projectName;
|
this.projectName = projectName;
|
||||||
this.clientPort = 32148;
|
this.clientPort = 32148;
|
||||||
guardType = "no";
|
guardType = "no";
|
||||||
isWarningMissArchJava = true;
|
|
||||||
environment = LauncherEnvironment.STD;
|
environment = LauncherEnvironment.STD;
|
||||||
secureCheckSalt = null;
|
secureCheckSalt = null;
|
||||||
secureCheckHash = null;
|
secureCheckHash = null;
|
||||||
|
@ -138,7 +111,6 @@ public LauncherConfig(String address, Map<String, byte[]> runtime, String projec
|
||||||
this.ecdsaPublicKey = null;
|
this.ecdsaPublicKey = null;
|
||||||
environment = env;
|
environment = env;
|
||||||
guardType = "no";
|
guardType = "no";
|
||||||
isWarningMissArchJava = true;
|
|
||||||
secureCheckSalt = null;
|
secureCheckSalt = null;
|
||||||
secureCheckHash = null;
|
secureCheckHash = null;
|
||||||
passwordEncryptKey = null;
|
passwordEncryptKey = null;
|
||||||
|
|
|
@ -45,42 +45,11 @@ public static class AuthAvailability {
|
||||||
public String name;
|
public String name;
|
||||||
@LauncherNetworkAPI
|
@LauncherNetworkAPI
|
||||||
public String displayName;
|
public String displayName;
|
||||||
@Deprecated
|
|
||||||
@LauncherNetworkAPI
|
|
||||||
public AuthType firstType;
|
|
||||||
@Deprecated
|
|
||||||
@LauncherNetworkAPI
|
|
||||||
public AuthType secondType;
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public AuthAvailability(String name, String displayName, AuthType firstType, AuthType secondType) {
|
|
||||||
this.name = name;
|
|
||||||
this.displayName = displayName;
|
|
||||||
this.firstType = firstType;
|
|
||||||
this.secondType = secondType;
|
|
||||||
this.details = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AuthAvailability(String name, String displayName, List<AuthAvailabilityDetails> details) {
|
public AuthAvailability(String name, String displayName, List<AuthAvailabilityDetails> details) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.displayName = displayName;
|
this.displayName = displayName;
|
||||||
this.details = details;
|
this.details = details;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public enum AuthType {
|
|
||||||
@LauncherNetworkAPI
|
|
||||||
PASSWORD,
|
|
||||||
@LauncherNetworkAPI
|
|
||||||
KEY,
|
|
||||||
@LauncherNetworkAPI
|
|
||||||
TOTP,
|
|
||||||
@LauncherNetworkAPI
|
|
||||||
OAUTH,
|
|
||||||
@LauncherNetworkAPI
|
|
||||||
NONE,
|
|
||||||
@LauncherNetworkAPI
|
|
||||||
OTHER
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,8 +35,6 @@ public class SimpleModuleManager implements LauncherModulesManager {
|
||||||
protected final LauncherTrustManager trustManager;
|
protected final LauncherTrustManager trustManager;
|
||||||
protected final PublicURLClassLoader classLoader = new PublicURLClassLoader(new URL[]{});
|
protected final PublicURLClassLoader classLoader = new PublicURLClassLoader(new URL[]{});
|
||||||
protected LauncherInitContext initContext;
|
protected LauncherInitContext initContext;
|
||||||
@Deprecated
|
|
||||||
protected LauncherTrustManager.CheckMode checkMode = LauncherTrustManager.CheckMode.WARN_IN_NOT_SIGNED;
|
|
||||||
|
|
||||||
public SimpleModuleManager(Path modulesDir, Path configDir) {
|
public SimpleModuleManager(Path modulesDir, Path configDir) {
|
||||||
modulesConfigManager = new SimpleModulesConfigManager(configDir);
|
modulesConfigManager = new SimpleModulesConfigManager(configDir);
|
||||||
|
@ -172,24 +170,6 @@ public LauncherModule loadModule(Path file) throws IOException {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public void checkModuleClass(Class<? extends LauncherModule> clazz, LauncherTrustManager.CheckMode mode) throws SecurityException {
|
|
||||||
if (trustManager == null) return;
|
|
||||||
X509Certificate[] certificates = getCertificates(clazz);
|
|
||||||
if (certificates == null) {
|
|
||||||
if (mode == LauncherTrustManager.CheckMode.EXCEPTION_IN_NOT_SIGNED)
|
|
||||||
throw new SecurityException(String.format("Class %s not signed", clazz.getName()));
|
|
||||||
else if (mode == LauncherTrustManager.CheckMode.WARN_IN_NOT_SIGNED)
|
|
||||||
LogHelper.warning("Class %s not signed", clazz.getName());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
trustManager.checkCertificatesSuccess(certificates, trustManager::stdCertificateChecker);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new SecurityException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public LauncherTrustManager.CheckClassResult checkModuleClass(Class<? extends LauncherModule> clazz) {
|
public LauncherTrustManager.CheckClassResult checkModuleClass(Class<? extends LauncherModule> clazz) {
|
||||||
if (trustManager == null) return null;
|
if (trustManager == null) return null;
|
||||||
X509Certificate[] certificates = getCertificates(clazz);
|
X509Certificate[] certificates = getCertificates(clazz);
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
import pro.gravit.launcher.hasher.FileNameMatcher;
|
import pro.gravit.launcher.hasher.FileNameMatcher;
|
||||||
import pro.gravit.launcher.profiles.optional.OptionalDepend;
|
import pro.gravit.launcher.profiles.optional.OptionalDepend;
|
||||||
import pro.gravit.launcher.profiles.optional.OptionalFile;
|
import pro.gravit.launcher.profiles.optional.OptionalFile;
|
||||||
import pro.gravit.launcher.profiles.optional.OptionalType;
|
|
||||||
import pro.gravit.launcher.profiles.optional.triggers.OptionalTrigger;
|
import pro.gravit.launcher.profiles.optional.triggers.OptionalTrigger;
|
||||||
import pro.gravit.utils.helper.IOHelper;
|
import pro.gravit.utils.helper.IOHelper;
|
||||||
import pro.gravit.utils.helper.VerifyHelper;
|
import pro.gravit.utils.helper.VerifyHelper;
|
||||||
|
@ -78,6 +77,8 @@ public final class ClientProfile implements Comparable<ClientProfile> {
|
||||||
private ProfileDefaultSettings settings = new ProfileDefaultSettings();
|
private ProfileDefaultSettings settings = new ProfileDefaultSettings();
|
||||||
@LauncherNetworkAPI
|
@LauncherNetworkAPI
|
||||||
private boolean updateFastCheck;
|
private boolean updateFastCheck;
|
||||||
|
@LauncherNetworkAPI
|
||||||
|
private boolean limited;
|
||||||
// Client launcher
|
// Client launcher
|
||||||
@LauncherNetworkAPI
|
@LauncherNetworkAPI
|
||||||
private String mainClass;
|
private String mainClass;
|
||||||
|
@ -257,13 +258,6 @@ public void updateOptionalGraph() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public OptionalFile getOptionalFile(String file, OptionalType type) {
|
|
||||||
for (OptionalFile f : updateOptional)
|
|
||||||
if (f.type.equals(type) && f.name.equals(file)) return f;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OptionalFile getOptionalFile(String file) {
|
public OptionalFile getOptionalFile(String file) {
|
||||||
for (OptionalFile f : updateOptional)
|
for (OptionalFile f : updateOptional)
|
||||||
if (f.name.equals(file)) return f;
|
if (f.name.equals(file)) return f;
|
||||||
|
@ -279,11 +273,6 @@ public int getServerPort() {
|
||||||
return profile == null ? 25565 : profile.serverPort;
|
return profile == null ? 25565 : profile.serverPort;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public InetSocketAddress getServerSocketAddress() {
|
|
||||||
return InetSocketAddress.createUnresolved(getServerAddress(), getServerPort());
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSortIndex() {
|
public int getSortIndex() {
|
||||||
return sortIndex;
|
return sortIndex;
|
||||||
}
|
}
|
||||||
|
@ -454,6 +443,10 @@ public void setRuntimeInClientConfig(RuntimeInClientConfig runtimeInClientConfig
|
||||||
this.runtimeInClientConfig = runtimeInClientConfig;
|
this.runtimeInClientConfig = runtimeInClientConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isLimited() {
|
||||||
|
return limited;
|
||||||
|
}
|
||||||
|
|
||||||
public enum Version {
|
public enum Version {
|
||||||
MC125("1.2.5", 29),
|
MC125("1.2.5", 29),
|
||||||
MC147("1.4.7", 51),
|
MC147("1.4.7", 51),
|
||||||
|
|
|
@ -1,31 +1,18 @@
|
||||||
package pro.gravit.launcher.profiles;
|
package pro.gravit.launcher.profiles;
|
||||||
|
|
||||||
import pro.gravit.launcher.serialize.HInput;
|
|
||||||
import pro.gravit.launcher.serialize.HOutput;
|
|
||||||
import pro.gravit.launcher.serialize.stream.StreamObject;
|
|
||||||
import pro.gravit.utils.helper.IOHelper;
|
import pro.gravit.utils.helper.IOHelper;
|
||||||
import pro.gravit.utils.helper.VerifyHelper;
|
import pro.gravit.utils.helper.VerifyHelper;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public final class PlayerProfile extends StreamObject {
|
public final class PlayerProfile {
|
||||||
|
|
||||||
public final UUID uuid;
|
public final UUID uuid;
|
||||||
public final String username;
|
public final String username;
|
||||||
public final Texture skin, cloak;
|
public final Texture skin, cloak;
|
||||||
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public PlayerProfile(HInput input) throws IOException {
|
|
||||||
uuid = input.readUUID();
|
|
||||||
username = VerifyHelper.verifyUsername(input.readString(64));
|
|
||||||
skin = input.readBoolean() ? new Texture(input) : null;
|
|
||||||
cloak = input.readBoolean() ? new Texture(input) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public PlayerProfile(UUID uuid, String username, Texture skin, Texture cloak) {
|
public PlayerProfile(UUID uuid, String username, Texture skin, Texture cloak) {
|
||||||
this.uuid = Objects.requireNonNull(uuid, "uuid");
|
this.uuid = Objects.requireNonNull(uuid, "uuid");
|
||||||
this.username = VerifyHelper.verifyUsername(username);
|
this.username = VerifyHelper.verifyUsername(username);
|
||||||
|
@ -41,19 +28,4 @@ public static UUID offlineUUID(String username) {
|
||||||
return UUID.nameUUIDFromBytes(IOHelper.encodeASCII("OfflinePlayer:" + username));
|
return UUID.nameUUIDFromBytes(IOHelper.encodeASCII("OfflinePlayer:" + username));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
@Deprecated
|
|
||||||
public void write(HOutput output) throws IOException {
|
|
||||||
output.writeUUID(uuid);
|
|
||||||
output.writeString(username, 64);
|
|
||||||
|
|
||||||
// Write textures
|
|
||||||
output.writeBoolean(skin != null);
|
|
||||||
if (skin != null)
|
|
||||||
skin.write(output);
|
|
||||||
output.writeBoolean(cloak != null);
|
|
||||||
if (cloak != null)
|
|
||||||
cloak.write(output);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package pro.gravit.launcher.profiles;
|
package pro.gravit.launcher.profiles;
|
||||||
|
|
||||||
import pro.gravit.launcher.serialize.HInput;
|
|
||||||
import pro.gravit.launcher.serialize.HOutput;
|
import pro.gravit.launcher.serialize.HOutput;
|
||||||
import pro.gravit.launcher.serialize.stream.StreamObject;
|
import pro.gravit.launcher.serialize.stream.StreamObject;
|
||||||
import pro.gravit.utils.helper.IOHelper;
|
import pro.gravit.utils.helper.IOHelper;
|
||||||
|
@ -25,14 +24,6 @@ public final class Texture extends StreamObject {
|
||||||
|
|
||||||
public final Map<String, String> metadata;
|
public final Map<String, String> metadata;
|
||||||
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public Texture(HInput input) throws IOException {
|
|
||||||
url = IOHelper.verifyURL(input.readASCII(2048));
|
|
||||||
digest = input.readByteArray(-DIGEST_ALGO.bytes);
|
|
||||||
metadata = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Texture(String url, boolean cloak) throws IOException {
|
public Texture(String url, boolean cloak) throws IOException {
|
||||||
this.url = IOHelper.verifyURL(url);
|
this.url = IOHelper.verifyURL(url);
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,4 @@
|
||||||
public class OptionalDepend {
|
public class OptionalDepend {
|
||||||
@LauncherNetworkAPI
|
@LauncherNetworkAPI
|
||||||
public String name;
|
public String name;
|
||||||
@Deprecated
|
|
||||||
@LauncherNetworkAPI
|
|
||||||
public OptionalType type;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,28 +2,11 @@
|
||||||
|
|
||||||
import pro.gravit.launcher.LauncherNetworkAPI;
|
import pro.gravit.launcher.LauncherNetworkAPI;
|
||||||
import pro.gravit.launcher.profiles.optional.actions.OptionalAction;
|
import pro.gravit.launcher.profiles.optional.actions.OptionalAction;
|
||||||
import pro.gravit.launcher.serialize.HInput;
|
|
||||||
import pro.gravit.launcher.serialize.HOutput;
|
|
||||||
import pro.gravit.utils.helper.LogHelper;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.function.BiConsumer;
|
|
||||||
|
|
||||||
public class OptionalFile {
|
public class OptionalFile {
|
||||||
@LauncherNetworkAPI
|
|
||||||
@Deprecated
|
|
||||||
public long permissions = 0L;
|
|
||||||
@LauncherNetworkAPI
|
|
||||||
@Deprecated
|
|
||||||
public String[] list;
|
|
||||||
@LauncherNetworkAPI
|
|
||||||
@Deprecated
|
|
||||||
public OptionalType type;
|
|
||||||
@LauncherNetworkAPI
|
@LauncherNetworkAPI
|
||||||
public List<OptionalAction> actions;
|
public List<OptionalAction> actions;
|
||||||
@LauncherNetworkAPI
|
@LauncherNetworkAPI
|
||||||
|
@ -37,9 +20,6 @@ public class OptionalFile {
|
||||||
@LauncherNetworkAPI
|
@LauncherNetworkAPI
|
||||||
public List<pro.gravit.launcher.profiles.optional.triggers.OptionalTrigger> triggersList;
|
public List<pro.gravit.launcher.profiles.optional.triggers.OptionalTrigger> triggersList;
|
||||||
@LauncherNetworkAPI
|
@LauncherNetworkAPI
|
||||||
@Deprecated
|
|
||||||
public OptionalTrigger[] triggers;
|
|
||||||
@LauncherNetworkAPI
|
|
||||||
public OptionalDepend[] dependenciesFile;
|
public OptionalDepend[] dependenciesFile;
|
||||||
@LauncherNetworkAPI
|
@LauncherNetworkAPI
|
||||||
public OptionalDepend[] conflictFile;
|
public OptionalDepend[] conflictFile;
|
||||||
|
@ -51,35 +31,8 @@ public class OptionalFile {
|
||||||
public int subTreeLevel = 1;
|
public int subTreeLevel = 1;
|
||||||
@LauncherNetworkAPI
|
@LauncherNetworkAPI
|
||||||
public boolean isPreset;
|
public boolean isPreset;
|
||||||
@Deprecated
|
@LauncherNetworkAPI
|
||||||
public transient Set<OptionalFile> dependenciesCount;
|
public boolean limited;
|
||||||
@Deprecated
|
|
||||||
private volatile transient Collection<BiConsumer<OptionalFile, Boolean>> watchList = null;
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public static OptionalType readType(HInput input) throws IOException {
|
|
||||||
int t = input.readInt();
|
|
||||||
OptionalType type;
|
|
||||||
switch (t) {
|
|
||||||
case 1:
|
|
||||||
type = OptionalType.FILE;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
type = OptionalType.CLASSPATH;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
type = OptionalType.JVMARGS;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
type = OptionalType.CLIENTARGS;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LogHelper.error("readType failed. Read int %d", t);
|
|
||||||
type = OptionalType.FILE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
|
@ -93,11 +46,6 @@ public int hashCode() {
|
||||||
return Objects.hash(name);
|
return Objects.hash(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public OptionalType getType() {
|
|
||||||
return OptionalType.FILE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
@ -109,54 +57,4 @@ public boolean isVisible() {
|
||||||
public boolean isMark() {
|
public boolean isMark() {
|
||||||
return mark;
|
return mark;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public long getPermissions() {
|
|
||||||
return permissions;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void writeType(HOutput output) throws IOException {
|
|
||||||
switch (type) {
|
|
||||||
|
|
||||||
case FILE:
|
|
||||||
output.writeInt(1);
|
|
||||||
break;
|
|
||||||
case CLASSPATH:
|
|
||||||
output.writeInt(2);
|
|
||||||
break;
|
|
||||||
case JVMARGS:
|
|
||||||
output.writeInt(3);
|
|
||||||
break;
|
|
||||||
case CLIENTARGS:
|
|
||||||
output.writeInt(4);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
output.writeInt(5);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public void registerWatcher(BiConsumer<OptionalFile, Boolean> watcher) {
|
|
||||||
if (watchList == null) watchList = ConcurrentHashMap.newKeySet();
|
|
||||||
watchList.add(watcher);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public void removeWatcher(BiConsumer<OptionalFile, Boolean> watcher) {
|
|
||||||
if (watchList == null) return;
|
|
||||||
watchList.remove(watcher);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public void clearAllWatchers() {
|
|
||||||
if (watchList == null) return;
|
|
||||||
watchList.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public void watchEvent(boolean isMark) {
|
|
||||||
if (watchList == null) return;
|
|
||||||
watchList.forEach((e) -> e.accept(this, isMark));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,99 +0,0 @@
|
||||||
package pro.gravit.launcher.profiles.optional;
|
|
||||||
|
|
||||||
import pro.gravit.launcher.profiles.optional.triggers.JavaTrigger;
|
|
||||||
import pro.gravit.launcher.profiles.optional.triggers.OSTrigger;
|
|
||||||
import pro.gravit.utils.helper.JVMHelper;
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public class OptionalTrigger {
|
|
||||||
public TriggerType type;
|
|
||||||
public boolean need = true;
|
|
||||||
public long value;
|
|
||||||
public long compareMode = 0;
|
|
||||||
|
|
||||||
public OptionalTrigger() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public OptionalTrigger(TriggerType type, long value) {
|
|
||||||
this.type = type;
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OptionalTrigger(TriggerType type, boolean need, long value, long compareMode) {
|
|
||||||
this.type = type;
|
|
||||||
this.need = need;
|
|
||||||
this.value = value;
|
|
||||||
this.compareMode = compareMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isTriggered() {
|
|
||||||
long test;
|
|
||||||
switch (type) {
|
|
||||||
|
|
||||||
case JAVA_VERSION:
|
|
||||||
test = JVMHelper.JVM_VERSION;
|
|
||||||
break;
|
|
||||||
case JAVA_BITS:
|
|
||||||
test = JVMHelper.JVM_BITS;
|
|
||||||
break;
|
|
||||||
case OS_BITS:
|
|
||||||
test = JVMHelper.OS_BITS;
|
|
||||||
break;
|
|
||||||
case OS_TYPE:
|
|
||||||
switch (JVMHelper.OS_TYPE) {
|
|
||||||
|
|
||||||
case MUSTDIE:
|
|
||||||
test = 0;
|
|
||||||
break;
|
|
||||||
case LINUX:
|
|
||||||
test = 1;
|
|
||||||
break;
|
|
||||||
case MACOSX:
|
|
||||||
test = 2;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (compareMode == 0) return test == value;
|
|
||||||
else if (compareMode < 0) return test < value;
|
|
||||||
else return test > value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public pro.gravit.launcher.profiles.optional.triggers.OptionalTrigger toTrigger() {
|
|
||||||
switch (type) {
|
|
||||||
case JAVA_VERSION: {
|
|
||||||
JavaTrigger trigger = new JavaTrigger((int) value, (int) value);
|
|
||||||
trigger.required = need;
|
|
||||||
if (compareMode > 0) {
|
|
||||||
trigger.maxVersion = 999;
|
|
||||||
} else if (compareMode < 0) {
|
|
||||||
trigger.minVersion = 0;
|
|
||||||
}
|
|
||||||
return trigger;
|
|
||||||
}
|
|
||||||
case JAVA_BITS:
|
|
||||||
case OS_BITS:
|
|
||||||
return null;
|
|
||||||
case OS_TYPE: {
|
|
||||||
JVMHelper.OS os;
|
|
||||||
if (value == 0) os = JVMHelper.OS.MUSTDIE;
|
|
||||||
else if (value == 1) os = JVMHelper.OS.LINUX;
|
|
||||||
else if (value == 2) os = JVMHelper.OS.MUSTDIE;
|
|
||||||
else throw new IllegalArgumentException(String.format("Os version %d unknown", value));
|
|
||||||
OSTrigger trigger = new OSTrigger(os);
|
|
||||||
trigger.required = need;
|
|
||||||
if (compareMode != 0) trigger.inverted = true;
|
|
||||||
return trigger;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum TriggerType {
|
|
||||||
JAVA_VERSION, JAVA_BITS, OS_BITS, OS_TYPE
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
package pro.gravit.launcher.profiles.optional;
|
|
||||||
|
|
||||||
import pro.gravit.launcher.LauncherNetworkAPI;
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public enum OptionalType {
|
|
||||||
@LauncherNetworkAPI
|
|
||||||
FILE,
|
|
||||||
@LauncherNetworkAPI
|
|
||||||
CLASSPATH,
|
|
||||||
@LauncherNetworkAPI
|
|
||||||
JVMARGS,
|
|
||||||
@LauncherNetworkAPI
|
|
||||||
CLIENTARGS
|
|
||||||
}
|
|
|
@ -11,21 +11,18 @@
|
||||||
|
|
||||||
public class OptionalView {
|
public class OptionalView {
|
||||||
public Set<OptionalFile> enabled = new HashSet<>();
|
public Set<OptionalFile> enabled = new HashSet<>();
|
||||||
@Deprecated
|
|
||||||
public Map<OptionalFile, Set<OptionalFile>> dependenciesCountMap = new HashMap<>();
|
|
||||||
public Map<OptionalFile, OptionalFileInstallInfo> installInfo = new HashMap<>();
|
public Map<OptionalFile, OptionalFileInstallInfo> installInfo = new HashMap<>();
|
||||||
public Set<OptionalFile> all;
|
public Set<OptionalFile> all;
|
||||||
|
|
||||||
public OptionalView(ClientProfile profile) {
|
public OptionalView(ClientProfile profile) {
|
||||||
this.all = profile.getOptional();
|
this.all = profile.getOptional();
|
||||||
for (OptionalFile f : this.all) {
|
for (OptionalFile f : this.all) {
|
||||||
if (f.mark) enable(f);
|
if (f.mark) enable(f, true, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public OptionalView(OptionalView view) {
|
public OptionalView(OptionalView view) {
|
||||||
this.enabled = new HashSet<>(view.enabled);
|
this.enabled = new HashSet<>(view.enabled);
|
||||||
this.dependenciesCountMap = new HashMap<>(view.dependenciesCountMap);
|
|
||||||
this.installInfo = new HashMap<>(view.installInfo);
|
this.installInfo = new HashMap<>(view.installInfo);
|
||||||
this.all = view.all;
|
this.all = view.all;
|
||||||
}
|
}
|
||||||
|
@ -66,51 +63,6 @@ public Set<OptionalAction> getDisabledActions() {
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public void enable(OptionalFile file) {
|
|
||||||
if (enabled.contains(file)) return;
|
|
||||||
enabled.add(file);
|
|
||||||
file.watchEvent(true);
|
|
||||||
if (file.dependencies != null) {
|
|
||||||
for (OptionalFile dep : file.dependencies) {
|
|
||||||
Set<OptionalFile> dependenciesCount = dependenciesCountMap.computeIfAbsent(dep, k -> new HashSet<>());
|
|
||||||
dependenciesCount.add(file);
|
|
||||||
enable(dep);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (file.conflict != null) {
|
|
||||||
for (OptionalFile conflict : file.conflict) {
|
|
||||||
disable(conflict);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public void disable(OptionalFile file) {
|
|
||||||
if (!enabled.remove(file)) return;
|
|
||||||
file.watchEvent(false);
|
|
||||||
Set<OptionalFile> dependenciesCount = dependenciesCountMap.get(file);
|
|
||||||
if (dependenciesCount != null) {
|
|
||||||
for (OptionalFile f : dependenciesCount) {
|
|
||||||
if (f.isPreset) continue;
|
|
||||||
disable(f);
|
|
||||||
}
|
|
||||||
dependenciesCount.clear();
|
|
||||||
}
|
|
||||||
if (file.dependencies != null) {
|
|
||||||
for (OptionalFile f : file.dependencies) {
|
|
||||||
if (!enabled.contains(f)) continue;
|
|
||||||
dependenciesCount = dependenciesCountMap.get(f);
|
|
||||||
if (dependenciesCount == null) {
|
|
||||||
disable(f);
|
|
||||||
} else if (dependenciesCount.size() <= 1) {
|
|
||||||
dependenciesCount.clear();
|
|
||||||
disable(f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void enable(OptionalFile file, boolean manual, BiConsumer<OptionalFile, Boolean> callback) {
|
public void enable(OptionalFile file, boolean manual, BiConsumer<OptionalFile, Boolean> callback) {
|
||||||
if (enabled.contains(file)) return;
|
if (enabled.contains(file)) return;
|
||||||
enabled.add(file);
|
enabled.add(file);
|
||||||
|
@ -128,7 +80,7 @@ public void enable(OptionalFile file, boolean manual, BiConsumer<OptionalFile, B
|
||||||
}
|
}
|
||||||
if (file.conflict != null) {
|
if (file.conflict != null) {
|
||||||
for (OptionalFile conflict : file.conflict) {
|
for (OptionalFile conflict : file.conflict) {
|
||||||
disable(conflict);
|
disable(conflict, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ public abstract class Request<R extends WebSocketEvent> implements WebSocketRequ
|
||||||
private static final List<ExtendedTokenCallback> extendedTokenCallbacks = new ArrayList<>(4);
|
private static final List<ExtendedTokenCallback> extendedTokenCallbacks = new ArrayList<>(4);
|
||||||
private static final List<BiConsumer<String, AuthRequestEvent.OAuthRequestEvent>> oauthChangeHandlers = new ArrayList<>(4);
|
private static final List<BiConsumer<String, AuthRequestEvent.OAuthRequestEvent>> oauthChangeHandlers = new ArrayList<>(4);
|
||||||
public static StdWebSocketService service;
|
public static StdWebSocketService service;
|
||||||
private static UUID session = UUID.randomUUID();
|
private static UUID session;
|
||||||
private static AuthRequestEvent.OAuthRequestEvent oauth;
|
private static AuthRequestEvent.OAuthRequestEvent oauth;
|
||||||
private static Map<String, String> extendedTokens;
|
private static Map<String, String> extendedTokens;
|
||||||
private static String authId;
|
private static String authId;
|
||||||
|
@ -110,20 +110,44 @@ public static String getRefreshToken() {
|
||||||
return oauth == null ? null : oauth.refreshToken;
|
return oauth == null ? null : oauth.refreshToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void reconnect() throws Exception {
|
public static RequestRestoreReport reconnect() throws Exception {
|
||||||
service.open();
|
service.open();
|
||||||
restore();
|
return restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void restore() throws Exception {
|
public static class RequestRestoreReport {
|
||||||
|
public final boolean legacySession;
|
||||||
|
public final boolean refreshed;
|
||||||
|
public final List<String> invalidExtendedTokens;
|
||||||
|
|
||||||
|
public RequestRestoreReport(boolean legacySession, boolean refreshed, List<String> invalidExtendedTokens) {
|
||||||
|
this.legacySession = legacySession;
|
||||||
|
this.refreshed = refreshed;
|
||||||
|
this.invalidExtendedTokens = invalidExtendedTokens;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RequestRestoreReport restore() throws Exception {
|
||||||
|
if (session != null) {
|
||||||
|
RestoreSessionRequest request = new RestoreSessionRequest(session);
|
||||||
|
request.request();
|
||||||
|
return new RequestRestoreReport(true, false, null);
|
||||||
|
} else {
|
||||||
|
boolean refreshed = false;
|
||||||
|
RestoreRequest request;
|
||||||
if(oauth != null) {
|
if(oauth != null) {
|
||||||
if (isTokenExpired() || oauth.accessToken == null) {
|
if (isTokenExpired() || oauth.accessToken == null) {
|
||||||
RefreshTokenRequest request = new RefreshTokenRequest(authId, oauth.refreshToken);
|
RefreshTokenRequest refreshRequest = new RefreshTokenRequest(authId, oauth.refreshToken);
|
||||||
RefreshTokenRequestEvent event = request.request();
|
RefreshTokenRequestEvent event = refreshRequest.request();
|
||||||
setOAuth(authId, event.oauth);
|
setOAuth(authId, event.oauth);
|
||||||
|
refreshed = true;
|
||||||
|
}
|
||||||
|
request = new RestoreRequest(authId, oauth.accessToken, extendedTokens, false);
|
||||||
|
} else {
|
||||||
|
request = new RestoreRequest(authId, null, extendedTokens, false);
|
||||||
}
|
}
|
||||||
RestoreRequest request = new RestoreRequest(authId, oauth.accessToken, extendedTokens, false);
|
|
||||||
RestoreRequestEvent event = request.request();
|
RestoreRequestEvent event = request.request();
|
||||||
|
List<String> invalidTokens = null;
|
||||||
if (event.invalidTokens != null && event.invalidTokens.size() > 0) {
|
if (event.invalidTokens != null && event.invalidTokens.size() > 0) {
|
||||||
boolean needRequest = false;
|
boolean needRequest = false;
|
||||||
Map<String, String> tokens = new HashMap<>();
|
Map<String, String> tokens = new HashMap<>();
|
||||||
|
@ -144,10 +168,9 @@ public static void restore() throws Exception {
|
||||||
LogHelper.warning("Tokens %s not restored", String.join(",", event.invalidTokens));
|
LogHelper.warning("Tokens %s not restored", String.join(",", event.invalidTokens));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
invalidTokens = event.invalidTokens;
|
||||||
}
|
}
|
||||||
} else if (session != null) {
|
return new RequestRestoreReport(false, refreshed, invalidTokens);
|
||||||
RestoreSessionRequest request = new RestoreSessionRequest(session);
|
|
||||||
request.request();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
import pro.gravit.launcher.request.auth.password.*;
|
import pro.gravit.launcher.request.auth.password.*;
|
||||||
import pro.gravit.launcher.request.websockets.WebSocketRequest;
|
import pro.gravit.launcher.request.websockets.WebSocketRequest;
|
||||||
import pro.gravit.utils.ProviderMap;
|
import pro.gravit.utils.ProviderMap;
|
||||||
import pro.gravit.utils.helper.VerifyHelper;
|
|
||||||
|
|
||||||
public final class AuthRequest extends Request<AuthRequestEvent> implements WebSocketRequest {
|
public final class AuthRequest extends Request<AuthRequestEvent> implements WebSocketRequest {
|
||||||
public static final ProviderMap<AuthPasswordInterface> providers = new ProviderMap<>();
|
public static final ProviderMap<AuthPasswordInterface> providers = new ProviderMap<>();
|
||||||
|
@ -22,33 +21,6 @@ public final class AuthRequest extends Request<AuthRequestEvent> implements WebS
|
||||||
@LauncherNetworkAPI
|
@LauncherNetworkAPI
|
||||||
private final ConnectTypes authType;
|
private final ConnectTypes authType;
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public AuthRequest(String login, byte[] password) {
|
|
||||||
this.login = VerifyHelper.verify(login, VerifyHelper.NOT_EMPTY, "Login can't be empty");
|
|
||||||
this.password = new AuthECPassword(password.clone());
|
|
||||||
auth_id = "";
|
|
||||||
getSession = true;
|
|
||||||
authType = ConnectTypes.CLIENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public AuthRequest(String login, byte[] password, String auth_id) {
|
|
||||||
this.login = VerifyHelper.verify(login, VerifyHelper.NOT_EMPTY, "Login can't be empty");
|
|
||||||
this.password = new AuthECPassword(password.clone());
|
|
||||||
this.auth_id = auth_id;
|
|
||||||
getSession = true;
|
|
||||||
authType = ConnectTypes.CLIENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public AuthRequest(String login, byte[] encryptedPassword, String auth_id, ConnectTypes authType) {
|
|
||||||
this.login = login;
|
|
||||||
this.password = new AuthECPassword(encryptedPassword.clone());
|
|
||||||
this.auth_id = auth_id;
|
|
||||||
this.authType = authType;
|
|
||||||
this.getSession = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AuthRequest(String login, String password, String auth_id, ConnectTypes authType) {
|
public AuthRequest(String login, String password, String auth_id, ConnectTypes authType) {
|
||||||
this.login = login;
|
this.login = login;
|
||||||
this.password = new AuthPlainPassword(password);
|
this.password = new AuthPlainPassword(password);
|
||||||
|
@ -65,12 +37,10 @@ public AuthRequest(String login, AuthPasswordInterface password, String auth_id,
|
||||||
this.authType = authType;
|
this.authType = authType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public static void registerProviders() {
|
public static void registerProviders() {
|
||||||
if (!registerProviders) {
|
if (!registerProviders) {
|
||||||
providers.register("plain", AuthPlainPassword.class);
|
providers.register("plain", AuthPlainPassword.class);
|
||||||
providers.register("rsa2", AuthRSAPassword.class);
|
providers.register("rsa2", AuthRSAPassword.class);
|
||||||
providers.register("rsa", AuthECPassword.class);
|
|
||||||
providers.register("aes", AuthAESPassword.class);
|
providers.register("aes", AuthAESPassword.class);
|
||||||
providers.register("2fa", Auth2FAPassword.class);
|
providers.register("2fa", Auth2FAPassword.class);
|
||||||
providers.register("multi", AuthMultiPassword.class);
|
providers.register("multi", AuthMultiPassword.class);
|
||||||
|
@ -88,9 +58,6 @@ public String getType() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum ConnectTypes {
|
public enum ConnectTypes {
|
||||||
@Deprecated
|
|
||||||
@LauncherNetworkAPI
|
|
||||||
SERVER,
|
|
||||||
@LauncherNetworkAPI
|
@LauncherNetworkAPI
|
||||||
CLIENT,
|
CLIENT,
|
||||||
@LauncherNetworkAPI
|
@LauncherNetworkAPI
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
package pro.gravit.launcher.request.auth.password;
|
|
||||||
|
|
||||||
import pro.gravit.launcher.LauncherNetworkAPI;
|
|
||||||
import pro.gravit.launcher.request.auth.AuthRequest;
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public class AuthECPassword implements AuthRequest.AuthPasswordInterface {
|
|
||||||
@LauncherNetworkAPI
|
|
||||||
public final byte[] password;
|
|
||||||
|
|
||||||
public AuthECPassword(byte[] password) {
|
|
||||||
this.password = password;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean check() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
package pro.gravit.launcher;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
public class PermissionTest {
|
||||||
|
@Test
|
||||||
|
public void testPermission() {
|
||||||
|
{
|
||||||
|
ClientPermissions permissions = new ClientPermissions();
|
||||||
|
permissions.addPerm("*");
|
||||||
|
Assertions.assertTrue(permissions.hasPerm("abcd"));
|
||||||
|
Assertions.assertTrue(permissions.hasPerm("t.a.c.d.f.*"));
|
||||||
|
Assertions.assertTrue(permissions.hasPerm("*"));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
ClientPermissions permissions = new ClientPermissions();
|
||||||
|
permissions.addPerm("launchserver.*");
|
||||||
|
Assertions.assertTrue(permissions.hasPerm("launchserver.*"));
|
||||||
|
Assertions.assertTrue(permissions.hasPerm("launchserver.abcd"));
|
||||||
|
Assertions.assertFalse(permissions.hasPerm("default.abcd"));
|
||||||
|
Assertions.assertFalse(permissions.hasPerm("nolaunchserver.abcd"));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
ClientPermissions permissions = new ClientPermissions();
|
||||||
|
permissions.addPerm("launchserver.*.prop");
|
||||||
|
Assertions.assertTrue(permissions.hasPerm("launchserver.ii.prop"));
|
||||||
|
Assertions.assertTrue(permissions.hasPerm("launchserver.ia.prop"));
|
||||||
|
Assertions.assertFalse(permissions.hasPerm("default.abcd"));
|
||||||
|
Assertions.assertFalse(permissions.hasPerm("launchserver.ia"));
|
||||||
|
Assertions.assertFalse(permissions.hasPerm("launchserver.ia.prop2"));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
ClientPermissions permissions = new ClientPermissions();
|
||||||
|
permissions.addPerm("launchserver.*.def.*.prop");
|
||||||
|
Assertions.assertTrue(permissions.hasPerm("launchserver.1.def.2.prop"));
|
||||||
|
Assertions.assertTrue(permissions.hasPerm("launchserver.none.def.none.prop"));
|
||||||
|
Assertions.assertTrue(permissions.hasPerm("launchserver.def.def.def.prop"));
|
||||||
|
Assertions.assertFalse(permissions.hasPerm("launchserver.*.*.prop"));
|
||||||
|
Assertions.assertFalse(permissions.hasPerm("launchserver.*.undef.*.prop"));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
ClientPermissions permissions = new ClientPermissions();
|
||||||
|
permissions.addPerm("launchserver.*.e.*.i.*.prop");
|
||||||
|
Assertions.assertTrue(permissions.hasPerm("launchserver.2.e.3.i.4.prop"));
|
||||||
|
Assertions.assertTrue(permissions.hasPerm("launchserver.12212.e.233455.i.2356436346346345345345345.prop"));
|
||||||
|
Assertions.assertFalse(permissions.hasPerm("launchserver.prop"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,10 +5,6 @@
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.security.InvalidKeyException;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.security.NoSuchProviderException;
|
|
||||||
import java.security.SignatureException;
|
|
||||||
import java.security.cert.*;
|
import java.security.cert.*;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -87,30 +83,6 @@ public void checkCertificatesSuccess(X509Certificate[] certs, CertificateChecker
|
||||||
throw new SecurityException(result.type.name());
|
throw new SecurityException(result.type.name());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public void checkCertificate(X509Certificate[] certs, CertificateChecker checker) throws CertificateException, NoSuchProviderException, NoSuchAlgorithmException, InvalidKeyException, SignatureException {
|
|
||||||
if (certs == null) throw new SecurityException("Object not signed");
|
|
||||||
for (int i = 0; i < certs.length; ++i) {
|
|
||||||
X509Certificate cert = certs[i];
|
|
||||||
if (trustCache.contains(cert)) {
|
|
||||||
//Добавляем в кеш все проверенные сертификаты
|
|
||||||
trustCache.addAll(Arrays.asList(certs).subList(0, i));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
X509Certificate signer = (i + 1 < certs.length) ? certs[i + 1] : null;
|
|
||||||
cert.checkValidity();
|
|
||||||
if (signer != null) {
|
|
||||||
cert.verify(signer.getPublicKey());
|
|
||||||
} else {
|
|
||||||
if (!isTrusted(cert)) {
|
|
||||||
throw new CertificateException(String.format("Certificate %s is not signed by a trusted signer", cert.getSubjectDN().getName()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
checker.check(cert, signer, i);
|
|
||||||
}
|
|
||||||
Collections.addAll(trustCache, certs);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isTrusted(X509Certificate certificate) throws CertificateEncodingException {
|
public boolean isTrusted(X509Certificate certificate) throws CertificateEncodingException {
|
||||||
//Java API не дает возможности вызвать getFingerprint
|
//Java API не дает возможности вызвать getFingerprint
|
||||||
//Oracle использует хак с кастом к sun.security.x509.X509CertImpl для проверки равенства сертификатов
|
//Oracle использует хак с кастом к sun.security.x509.X509CertImpl для проверки равенства сертификатов
|
||||||
|
@ -167,11 +139,6 @@ public enum CheckClassResultType {
|
||||||
UNCOMPAT
|
UNCOMPAT
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public enum CheckMode {
|
|
||||||
EXCEPTION_IN_NOT_SIGNED, WARN_IN_NOT_SIGNED, NONE_IN_NOT_SIGNED
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface CertificateChecker {
|
public interface CertificateChecker {
|
||||||
void check(X509Certificate cert, X509Certificate signer, int number) throws SecurityException;
|
void check(X509Certificate cert, X509Certificate signer, int number) throws SecurityException;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
import pro.gravit.launcher.serialize.HOutput;
|
import pro.gravit.launcher.serialize.HOutput;
|
||||||
import pro.gravit.launcher.serialize.stream.EnumSerializer;
|
import pro.gravit.launcher.serialize.stream.EnumSerializer;
|
||||||
import pro.gravit.utils.helper.IOHelper;
|
import pro.gravit.utils.helper.IOHelper;
|
||||||
import pro.gravit.utils.helper.LogHelper;
|
|
||||||
import pro.gravit.utils.helper.VerifyHelper;
|
import pro.gravit.utils.helper.VerifyHelper;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -68,40 +67,6 @@ public void remove(String name) {
|
||||||
map.remove(name);
|
map.remove(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public void removeR(String name) {
|
|
||||||
LinkedList<String> dirs = new LinkedList<>();
|
|
||||||
StringTokenizer t = new StringTokenizer(name, "/");
|
|
||||||
while (t.hasMoreTokens()) {
|
|
||||||
dirs.add(t.nextToken());
|
|
||||||
}
|
|
||||||
Map<String, HashedEntry> current = map;
|
|
||||||
for (String s : dirs) {
|
|
||||||
HashedEntry e = current.get(s);
|
|
||||||
if (e == null) {
|
|
||||||
if (LogHelper.isDebugEnabled()) {
|
|
||||||
LogHelper.debug("Null %s", s);
|
|
||||||
}
|
|
||||||
if (LogHelper.isDebugEnabled()) {
|
|
||||||
for (String x : current.keySet()) LogHelper.debug("Contains %s", x);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (e.getType() == Type.DIR) {
|
|
||||||
current = ((HashedDir) e).map;
|
|
||||||
if (LogHelper.isDebugEnabled()) {
|
|
||||||
LogHelper.debug("Found dir %s", s);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
current.remove(s);
|
|
||||||
if (LogHelper.isDebugEnabled()) {
|
|
||||||
LogHelper.debug("Found filename %s", s);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void moveTo(String elementName, HashedDir target, String targetElementName) {
|
public void moveTo(String elementName, HashedDir target, String targetElementName) {
|
||||||
HashedEntry entry = map.remove(elementName);
|
HashedEntry entry = map.remove(elementName);
|
||||||
target.map.put(targetElementName, entry);
|
target.map.put(targetElementName, entry);
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
import java.util.Timer;
|
import java.util.Timer;
|
||||||
import java.util.TimerTask;
|
import java.util.TimerTask;
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public class GarbageManager {
|
public class GarbageManager {
|
||||||
private static final Timer timer = new Timer("GarbageTimer");
|
private static final Timer timer = new Timer("GarbageTimer");
|
||||||
private static final Set<Entry> NEED_GARBARE_COLLECTION = new HashSet<>();
|
private static final Set<Entry> NEED_GARBARE_COLLECTION = new HashSet<>();
|
||||||
|
|
|
@ -6,7 +6,7 @@ public final class Version implements Comparable<Version> {
|
||||||
|
|
||||||
public static final int MAJOR = 5;
|
public static final int MAJOR = 5;
|
||||||
public static final int MINOR = 2;
|
public static final int MINOR = 2;
|
||||||
public static final int PATCH = 2;
|
public static final int PATCH = 3;
|
||||||
public static final int BUILD = 1;
|
public static final int BUILD = 1;
|
||||||
public static final Version.Type RELEASE = Type.STABLE;
|
public static final Version.Type RELEASE = Type.STABLE;
|
||||||
public final int major;
|
public final int major;
|
||||||
|
|
|
@ -20,7 +20,6 @@ public String getUsageDescription() {
|
||||||
public void invoke(String... args) {
|
public void invoke(String... args) {
|
||||||
LogHelper.subInfo("Performing full GC");
|
LogHelper.subInfo("Performing full GC");
|
||||||
JVMHelper.fullGC();
|
JVMHelper.fullGC();
|
||||||
GarbageManager.gc();
|
|
||||||
// Print memory usage
|
// Print memory usage
|
||||||
long max = JVMHelper.RUNTIME.maxMemory() >> 20;
|
long max = JVMHelper.RUNTIME.maxMemory() >> 20;
|
||||||
long free = JVMHelper.RUNTIME.freeMemory() >> 20;
|
long free = JVMHelper.RUNTIME.freeMemory() >> 20;
|
||||||
|
|
|
@ -151,6 +151,15 @@ public static JavaVersionAndBuild getJavaVersion(String version) {
|
||||||
result.version = Integer.parseInt(version.substring(0, dot));
|
result.version = Integer.parseInt(version.substring(0, dot));
|
||||||
dot = version.lastIndexOf(".");
|
dot = version.lastIndexOf(".");
|
||||||
result.build = Integer.parseInt(version.substring(dot + 1));
|
result.build = Integer.parseInt(version.substring(dot + 1));
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
if(version.endsWith("-ea")) {
|
||||||
|
version = version.substring(0, version.length()-3);
|
||||||
|
}
|
||||||
|
result.version = Integer.parseInt(version);
|
||||||
|
result.build = 0;
|
||||||
|
} catch (NumberFormatException ignored) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -10,10 +10,7 @@
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.time.format.DateTimeFormatter;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
@ -135,11 +132,6 @@ public static void setDevEnabled(boolean stacktraceEnabled) {
|
||||||
impl.setDevEnabled(stacktraceEnabled);
|
impl.setDevEnabled(stacktraceEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public static String getDataTime() {
|
|
||||||
return DateTimeFormatter.ofPattern("yyyy.MM.dd HH:mm:ss", Locale.US).format(LocalDateTime.now());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void log(Level level, String message, boolean sub) {
|
public static void log(Level level, String message, boolean sub) {
|
||||||
impl.log(level, message, sub);
|
impl.log(level, message, sub);
|
||||||
}
|
}
|
||||||
|
@ -205,9 +197,6 @@ public enum OutputTypes {
|
||||||
PLAIN,
|
PLAIN,
|
||||||
@LauncherNetworkAPI
|
@LauncherNetworkAPI
|
||||||
JANSI,
|
JANSI,
|
||||||
@LauncherNetworkAPI
|
|
||||||
@Deprecated
|
|
||||||
HTML
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum Level {
|
public enum Level {
|
||||||
|
|
|
@ -83,11 +83,6 @@ public static byte[] digest(DigestAlgorithm algo, URL url) throws IOException {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public static KeyPair genECKeyPair(SecureRandom random) {
|
|
||||||
return genECDSAKeyPair(random);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static KeyPair genECDSAKeyPair(SecureRandom random) {
|
public static KeyPair genECDSAKeyPair(SecureRandom random) {
|
||||||
try {
|
try {
|
||||||
KeyPairGenerator generator = KeyPairGenerator.getInstance(EC_ALGO);
|
KeyPairGenerator generator = KeyPairGenerator.getInstance(EC_ALGO);
|
||||||
|
@ -409,16 +404,6 @@ public static String toHex(byte[] bytes) {
|
||||||
return new String(hex);
|
return new String(hex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public static ECPublicKey toPublicECKey(byte[] bytes) throws InvalidKeySpecException {
|
|
||||||
return toPublicECDSAKey(bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public static ECPrivateKey toPrivateECKey(byte[] bytes) throws InvalidKeySpecException {
|
|
||||||
return toPrivateECDSAKey(bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ECPublicKey toPublicECDSAKey(byte[] bytes) throws InvalidKeySpecException {
|
public static ECPublicKey toPublicECDSAKey(byte[] bytes) throws InvalidKeySpecException {
|
||||||
return (ECPublicKey) newECDSAKeyFactory().generatePublic(new X509EncodedKeySpec(bytes));
|
return (ECPublicKey) newECDSAKeyFactory().generatePublic(new X509EncodedKeySpec(bytes));
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,12 +15,14 @@
|
||||||
import pro.gravit.launcher.request.Request;
|
import pro.gravit.launcher.request.Request;
|
||||||
import pro.gravit.launcher.request.auth.AuthRequest;
|
import pro.gravit.launcher.request.auth.AuthRequest;
|
||||||
import pro.gravit.launcher.request.auth.GetAvailabilityAuthRequest;
|
import pro.gravit.launcher.request.auth.GetAvailabilityAuthRequest;
|
||||||
|
import pro.gravit.launcher.request.auth.RestoreRequest;
|
||||||
import pro.gravit.launcher.request.update.ProfilesRequest;
|
import pro.gravit.launcher.request.update.ProfilesRequest;
|
||||||
import pro.gravit.launcher.server.setup.ServerWrapperSetup;
|
import pro.gravit.launcher.server.setup.ServerWrapperSetup;
|
||||||
import pro.gravit.utils.PublicURLClassLoader;
|
import pro.gravit.utils.PublicURLClassLoader;
|
||||||
import pro.gravit.utils.helper.IOHelper;
|
import pro.gravit.utils.helper.IOHelper;
|
||||||
import pro.gravit.utils.helper.LogHelper;
|
import pro.gravit.utils.helper.LogHelper;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.lang.invoke.MethodHandle;
|
import java.lang.invoke.MethodHandle;
|
||||||
import java.lang.invoke.MethodHandles;
|
import java.lang.invoke.MethodHandles;
|
||||||
import java.lang.invoke.MethodType;
|
import java.lang.invoke.MethodType;
|
||||||
|
@ -28,16 +30,11 @@
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.Arrays;
|
import java.util.*;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class ServerWrapper extends JsonConfigurable<ServerWrapper.Config> {
|
public class ServerWrapper extends JsonConfigurable<ServerWrapper.Config> {
|
||||||
public static final Path modulesDir = Paths.get(System.getProperty("serverwrapper.modulesDir", "modules"));
|
|
||||||
public static final Path modulesConfigDir = Paths.get(System.getProperty("serverwrapper.modulesConfigDir", "modules-config"));
|
|
||||||
public static final Path configFile = Paths.get(System.getProperty("serverwrapper.configFile", "ServerWrapperConfig.json"));
|
public static final Path configFile = Paths.get(System.getProperty("serverwrapper.configFile", "ServerWrapperConfig.json"));
|
||||||
public static final boolean disableSetup = Boolean.parseBoolean(System.getProperty("serverwrapper.disableSetup", "false"));
|
public static final boolean disableSetup = Boolean.parseBoolean(System.getProperty("serverwrapper.disableSetup", "false"));
|
||||||
public static ServerWrapperModulesManager modulesManager;
|
|
||||||
public static ServerWrapper wrapper;
|
public static ServerWrapper wrapper;
|
||||||
public Config config;
|
public Config config;
|
||||||
public PublicURLClassLoader ucp;
|
public PublicURLClassLoader ucp;
|
||||||
|
@ -51,48 +48,29 @@ public ServerWrapper(Type type, Path configPath) {
|
||||||
super(type, configPath);
|
super(type, configPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void initGson(ServerWrapperModulesManager modulesManager) {
|
public static void initGson() {
|
||||||
Launcher.gsonManager = new ServerWrapperGsonManager(modulesManager);
|
Launcher.gsonManager = new ServerWrapperGsonManager();
|
||||||
Launcher.gsonManager.initGson();
|
Launcher.gsonManager.initGson();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String... args) throws Throwable {
|
public static void main(String... args) throws Throwable {
|
||||||
LogHelper.printVersion("ServerWrapper");
|
LogHelper.printVersion("ServerWrapper");
|
||||||
LogHelper.printLicense("ServerWrapper");
|
LogHelper.printLicense("ServerWrapper");
|
||||||
modulesManager = new ServerWrapperModulesManager(modulesDir, modulesConfigDir);
|
|
||||||
modulesManager.autoload();
|
|
||||||
modulesManager.initModules(null);
|
|
||||||
ServerWrapper.wrapper = new ServerWrapper(ServerWrapper.Config.class, configFile);
|
ServerWrapper.wrapper = new ServerWrapper(ServerWrapper.Config.class, configFile);
|
||||||
ServerWrapper.wrapper.run(args);
|
ServerWrapper.wrapper.run(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean auth() {
|
public void restore() throws Exception {
|
||||||
try {
|
if(config.oauth != null) {
|
||||||
Launcher.getConfig();
|
Request.setOAuth(config.authId, config.oauth, config.oauthExpireTime);
|
||||||
AuthRequest request = new AuthRequest(config.login, config.password, config.auth_id, AuthRequest.ConnectTypes.API);
|
|
||||||
AuthRequestEvent authResult = request.request();
|
|
||||||
if (config.saveSession) {
|
|
||||||
if (authResult.oauth != null) {
|
|
||||||
Request.setOAuth(config.auth_id, authResult.oauth);
|
|
||||||
config.oauth = authResult.oauth;
|
|
||||||
config.oauthExpireTime = Request.getTokenExpiredTime();
|
|
||||||
} else {
|
|
||||||
Request.setSession(authResult.session);
|
|
||||||
}
|
}
|
||||||
saveConfig();
|
if(config.extendedTokens != null) {
|
||||||
}
|
Request.addAllExtendedToken(config.extendedTokens);
|
||||||
permissions = authResult.permissions;
|
|
||||||
playerProfile = authResult.playerProfile;
|
|
||||||
return true;
|
|
||||||
} catch (Throwable e) {
|
|
||||||
LogHelper.error(e);
|
|
||||||
if (config.stopOnError) System.exit(-1);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
Request.restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProfilesRequestEvent getProfiles() {
|
public ProfilesRequestEvent getProfiles() throws Exception {
|
||||||
try {
|
|
||||||
ProfilesRequestEvent result = new ProfilesRequest().request();
|
ProfilesRequestEvent result = new ProfilesRequest().request();
|
||||||
for (ClientProfile p : result.profiles) {
|
for (ClientProfile p : result.profiles) {
|
||||||
LogHelper.debug("Get profile: %s", p.getTitle());
|
LogHelper.debug("Get profile: %s", p.getTitle());
|
||||||
|
@ -113,15 +91,10 @@ public ProfilesRequestEvent getProfiles() {
|
||||||
LogHelper.warning("Not connected to ServerProfile. May be serverName incorrect?");
|
LogHelper.warning("Not connected to ServerProfile. May be serverName incorrect?");
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
} catch (Throwable e) {
|
|
||||||
LogHelper.error(e);
|
|
||||||
if (config.stopOnError) System.exit(-1);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void run(String... args) throws Throwable {
|
public void run(String... args) throws Throwable {
|
||||||
initGson(modulesManager);
|
initGson();
|
||||||
AuthRequest.registerProviders();
|
AuthRequest.registerProviders();
|
||||||
GetAvailabilityAuthRequest.registerProviders();
|
GetAvailabilityAuthRequest.registerProviders();
|
||||||
OptionalAction.registerProviders();
|
OptionalAction.registerProviders();
|
||||||
|
@ -133,7 +106,6 @@ public void run(String... args) throws Throwable {
|
||||||
setup.run();
|
setup.run();
|
||||||
System.exit(0);
|
System.exit(0);
|
||||||
}
|
}
|
||||||
modulesManager.invokeEvent(new PreConfigPhase());
|
|
||||||
LogHelper.debug("Read ServerWrapperConfig.json");
|
LogHelper.debug("Read ServerWrapperConfig.json");
|
||||||
loadConfig();
|
loadConfig();
|
||||||
updateLauncherConfig();
|
updateLauncherConfig();
|
||||||
|
@ -141,49 +113,29 @@ public void run(String... args) throws Throwable {
|
||||||
else Launcher.applyLauncherEnv(LauncherConfig.LauncherEnvironment.STD);
|
else Launcher.applyLauncherEnv(LauncherConfig.LauncherEnvironment.STD);
|
||||||
if (config.logFile != null) LogHelper.addOutput(IOHelper.newWriter(Paths.get(config.logFile), true));
|
if (config.logFile != null) LogHelper.addOutput(IOHelper.newWriter(Paths.get(config.logFile), true));
|
||||||
{
|
{
|
||||||
if (config.saveSession) {
|
restore();
|
||||||
boolean needRestore = false;
|
|
||||||
if (config.oauth != null) {
|
|
||||||
Request.setOAuth(config.auth_id, config.oauth, config.oauthExpireTime);
|
|
||||||
needRestore = true;
|
|
||||||
} else if (config.session != null) {
|
|
||||||
Request.setSession(config.session);
|
|
||||||
needRestore = true;
|
|
||||||
} else {
|
|
||||||
auth();
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
if (needRestore)
|
|
||||||
Request.restore();
|
|
||||||
} catch (Exception e) {
|
|
||||||
LogHelper.error(e);
|
|
||||||
auth();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
auth();
|
|
||||||
}
|
|
||||||
getProfiles();
|
getProfiles();
|
||||||
}
|
}
|
||||||
modulesManager.invokeEvent(new ServerWrapperInitPhase(this));
|
|
||||||
String classname = (config.mainclass == null || config.mainclass.isEmpty()) ? args[0] : config.mainclass;
|
String classname = (config.mainclass == null || config.mainclass.isEmpty()) ? args[0] : config.mainclass;
|
||||||
if (classname.length() == 0) {
|
if (classname.length() == 0) {
|
||||||
LogHelper.error("MainClass not found. Please set MainClass for ServerWrapper.cfg or first commandline argument");
|
LogHelper.error("MainClass not found. Please set MainClass for ServerWrapper.json or first commandline argument");
|
||||||
if (config.stopOnError) System.exit(-1);
|
System.exit(-1);
|
||||||
|
}
|
||||||
|
if(config.oauth == null && ( config.extendedTokens == null || config.extendedTokens.isEmpty())) {
|
||||||
|
LogHelper.error("Auth not configured. Please use 'java -jar ServerWrapper.jar setup'");
|
||||||
|
System.exit(-1);
|
||||||
}
|
}
|
||||||
Class<?> mainClass;
|
Class<?> mainClass;
|
||||||
if (config.customClassPath) {
|
if (config.classpath != null && !config.classpath.isEmpty()) {
|
||||||
if (config.classpath == null)
|
|
||||||
throw new UnsupportedOperationException("classpath is null, customClassPath not available");
|
|
||||||
String[] cp = config.classpath.split(":");
|
|
||||||
if (!ServerAgent.isAgentStarted()) {
|
if (!ServerAgent.isAgentStarted()) {
|
||||||
LogHelper.warning("JavaAgent not found. Using URLClassLoader");
|
LogHelper.warning("JavaAgent not found. Using URLClassLoader");
|
||||||
URL[] urls = Arrays.stream(cp).map(Paths::get).map(IOHelper::toURL).toArray(URL[]::new);
|
URL[] urls = config.classpath.stream().map(Paths::get).map(IOHelper::toURL).toArray(URL[]::new);
|
||||||
ucp = new PublicURLClassLoader(urls);
|
ucp = new PublicURLClassLoader(urls);
|
||||||
Thread.currentThread().setContextClassLoader(ucp);
|
Thread.currentThread().setContextClassLoader(ucp);
|
||||||
loader = ucp;
|
loader = ucp;
|
||||||
} else {
|
} else {
|
||||||
LogHelper.info("Found %d custom classpath elements", cp.length);
|
LogHelper.info("Found %d custom classpath elements", config.classpath.size());
|
||||||
for (String c : cp)
|
for (String c : config.classpath)
|
||||||
ServerAgent.addJVMClassPath(c);
|
ServerAgent.addJVMClassPath(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -200,20 +152,15 @@ public void run(String... args) throws Throwable {
|
||||||
if (loader != null) mainClass = Class.forName(classname, true, loader);
|
if (loader != null) mainClass = Class.forName(classname, true, loader);
|
||||||
else mainClass = Class.forName(classname);
|
else mainClass = Class.forName(classname);
|
||||||
MethodHandle mainMethod = MethodHandles.publicLookup().findStatic(mainClass, "main", MethodType.methodType(void.class, String[].class));
|
MethodHandle mainMethod = MethodHandles.publicLookup().findStatic(mainClass, "main", MethodType.methodType(void.class, String[].class));
|
||||||
modulesManager.invokeEvent(new PostInitPhase());
|
|
||||||
Request.service.reconnectCallback = () ->
|
Request.service.reconnectCallback = () ->
|
||||||
{
|
{
|
||||||
LogHelper.debug("WebSocket connect closed. Try reconnect");
|
LogHelper.debug("WebSocket connect closed. Try reconnect");
|
||||||
if (config.saveSession) {
|
|
||||||
try {
|
try {
|
||||||
Request.restore();
|
Request.reconnect();
|
||||||
} catch (Exception e) {
|
|
||||||
auth();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
auth();
|
|
||||||
}
|
|
||||||
getProfiles();
|
getProfiles();
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogHelper.error(e);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
LogHelper.info("ServerWrapper: Project %s, LaunchServer address: %s. Title: %s", config.projectname, config.address, Launcher.profile != null ? Launcher.profile.getTitle() : "unknown");
|
LogHelper.info("ServerWrapper: Project %s, LaunchServer address: %s. Title: %s", config.projectname, config.address, Launcher.profile != null ? Launcher.profile.getTitle() : "unknown");
|
||||||
LogHelper.info("Minecraft Version (for profile): %s", wrapper.profile == null ? "unknown" : wrapper.profile.getVersion().name);
|
LogHelper.info("Minecraft Version (for profile): %s", wrapper.profile == null ? "unknown" : wrapper.profile.getVersion().name);
|
||||||
|
@ -226,9 +173,9 @@ public void run(String... args) throws Throwable {
|
||||||
System.arraycopy(args, 1, real_args, 0, args.length - 1);
|
System.arraycopy(args, 1, real_args, 0, args.length - 1);
|
||||||
} else real_args = args;
|
} else real_args = args;
|
||||||
|
|
||||||
mainMethod.invoke(real_args);
|
mainMethod.invoke((Object) real_args);
|
||||||
} else {
|
} else {
|
||||||
mainMethod.invoke(config.args);
|
mainMethod.invoke((Object) config.args.toArray(new String[0]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,43 +200,29 @@ public Config getDefaultConfig() {
|
||||||
Config newConfig = new Config();
|
Config newConfig = new Config();
|
||||||
newConfig.serverName = "your server name";
|
newConfig.serverName = "your server name";
|
||||||
newConfig.projectname = "MineCraft";
|
newConfig.projectname = "MineCraft";
|
||||||
newConfig.login = "login";
|
|
||||||
newConfig.password = "password";
|
|
||||||
newConfig.mainclass = "";
|
newConfig.mainclass = "";
|
||||||
newConfig.syncAuth = true;
|
newConfig.extendedTokens = new HashMap<>();
|
||||||
newConfig.stopOnError = true;
|
newConfig.args = new ArrayList<>();
|
||||||
newConfig.saveSession = true;
|
newConfig.classpath = new ArrayList<>();
|
||||||
newConfig.reconnectCount = 10;
|
|
||||||
newConfig.reconnectSleep = 1000;
|
|
||||||
newConfig.address = "ws://localhost:9274/api";
|
newConfig.address = "ws://localhost:9274/api";
|
||||||
newConfig.env = LauncherConfig.LauncherEnvironment.STD;
|
newConfig.env = LauncherConfig.LauncherEnvironment.STD;
|
||||||
return newConfig;
|
return newConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class Config {
|
public static final class Config {
|
||||||
@Deprecated
|
|
||||||
public String title;
|
|
||||||
public String projectname;
|
public String projectname;
|
||||||
public String address;
|
public String address;
|
||||||
public String serverName;
|
public String serverName;
|
||||||
public int reconnectCount;
|
|
||||||
public int reconnectSleep;
|
|
||||||
public boolean customClassPath;
|
|
||||||
public boolean autoloadLibraries;
|
public boolean autoloadLibraries;
|
||||||
public boolean stopOnError;
|
|
||||||
public boolean syncAuth;
|
|
||||||
public String logFile;
|
public String logFile;
|
||||||
public String classpath;
|
public List<String> classpath;
|
||||||
public String librariesDir;
|
public String librariesDir;
|
||||||
public String mainclass;
|
public String mainclass;
|
||||||
public String login;
|
public List<String> args;
|
||||||
public String[] args;
|
public String authId;
|
||||||
public String password;
|
|
||||||
public String auth_id = "";
|
|
||||||
public boolean saveSession;
|
|
||||||
public AuthRequestEvent.OAuthRequestEvent oauth;
|
public AuthRequestEvent.OAuthRequestEvent oauth;
|
||||||
public long oauthExpireTime;
|
public long oauthExpireTime;
|
||||||
public UUID session;
|
public Map<String, String> extendedTokens;
|
||||||
public LauncherConfig.LauncherEnvironment env;
|
public LauncherConfig.LauncherEnvironment env;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,16 +6,13 @@
|
||||||
import pro.gravit.launcher.request.websockets.ClientWebSocketService;
|
import pro.gravit.launcher.request.websockets.ClientWebSocketService;
|
||||||
|
|
||||||
public class ServerWrapperGsonManager extends GsonManager {
|
public class ServerWrapperGsonManager extends GsonManager {
|
||||||
private final ServerWrapperModulesManager modulesManager;
|
|
||||||
|
|
||||||
public ServerWrapperGsonManager(ServerWrapperModulesManager modulesManager) {
|
public ServerWrapperGsonManager() {
|
||||||
this.modulesManager = modulesManager;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void registerAdapters(GsonBuilder builder) {
|
public void registerAdapters(GsonBuilder builder) {
|
||||||
super.registerAdapters(builder);
|
super.registerAdapters(builder);
|
||||||
ClientWebSocketService.appendTypeAdapters(builder);
|
ClientWebSocketService.appendTypeAdapters(builder);
|
||||||
modulesManager.invokeEvent(new PreGsonPhase(builder));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
package pro.gravit.launcher.server;
|
|
||||||
|
|
||||||
import pro.gravit.launcher.modules.LauncherInitContext;
|
|
||||||
|
|
||||||
public class ServerWrapperInitContext implements LauncherInitContext {
|
|
||||||
public final ServerWrapper serverWrapper;
|
|
||||||
|
|
||||||
public ServerWrapperInitContext(ServerWrapper serverWrapper) {
|
|
||||||
this.serverWrapper = serverWrapper;
|
|
||||||
}
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue