[REFACTOR] Remove AuthProvider/AuthHandler support

This commit is contained in:
Gravita 2021-09-22 12:45:48 +07:00
parent fbbde7991e
commit 9b55e243e7
51 changed files with 55 additions and 2095 deletions

View file

@ -274,14 +274,7 @@ public void invoke(String... args) throws Exception {
logger.error("Pair not found");
return;
}
if (pair.isUseCore()) {
pair.core.close();
} else {
pair.provider.close();
pair.handler.close();
pair.handler = null;
pair.provider = null;
}
pair.core.close();
pair.core = new RejectAuthCoreProvider();
pair.core.init(instance);
}

View file

@ -11,17 +11,14 @@
import pro.gravit.launcher.request.auth.AuthRequest;
import pro.gravit.launcher.request.auth.GetAvailabilityAuthRequest;
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.protect.ProtectHandler;
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.texture.TextureProvider;
import pro.gravit.launchserver.components.Component;
import pro.gravit.launchserver.config.LaunchServerConfig;
import pro.gravit.launchserver.config.LaunchServerRuntimeConfig;
import pro.gravit.launchserver.dao.provider.DaoProvider;
import pro.gravit.launchserver.manangers.CertificateManager;
import pro.gravit.launchserver.manangers.LaunchServerGsonManager;
import pro.gravit.launchserver.modules.impl.LaunchServerModulesManager;
@ -201,13 +198,10 @@ public static void initGson(LaunchServerModulesManager modulesManager) {
public static void registerAll() {
AuthCoreProvider.registerProviders();
PasswordVerifier.registerProviders();
AuthHandler.registerHandlers();
AuthProvider.registerProviders();
TextureProvider.registerProviders();
Component.registerComponents();
ProtectHandler.registerHandlers();
WebSocketService.registerResponses();
DaoProvider.registerProviders();
AuthRequest.registerProviders();
GetAvailabilityAuthRequest.registerProviders();
HWIDProvider.registerProviders();

View file

@ -3,8 +3,6 @@
import pro.gravit.launchserver.LaunchServer;
import pro.gravit.launchserver.auth.core.AuthCoreProvider;
import pro.gravit.launchserver.auth.core.AuthSocialProvider;
import pro.gravit.launchserver.auth.handler.AuthHandler;
import pro.gravit.launchserver.auth.provider.AuthProvider;
import pro.gravit.launchserver.auth.texture.TextureProvider;
import java.io.IOException;
@ -16,20 +14,12 @@ public final class AuthProviderPair {
public boolean isDefault = true;
public AuthCoreProvider core;
public AuthSocialProvider social;
public AuthProvider provider;
public AuthHandler handler;
public TextureProvider textureProvider;
public Map<String, String> links;
public transient String name;
public transient Set<String> features;
public String displayName;
public AuthProviderPair(AuthProvider provider, AuthHandler handler, TextureProvider textureProvider) {
this.provider = provider;
this.handler = handler;
this.textureProvider = textureProvider;
}
public AuthProviderPair(AuthCoreProvider core, TextureProvider textureProvider) {
this.core = core;
this.textureProvider = textureProvider;
@ -80,23 +70,12 @@ public final <T> T isSupport(Class<T> clazz) {
public final void init(LaunchServer srv, String name) {
this.name = name;
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);
features = new HashSet<>();
getFeatures(core.getClass(), features);
if (social != null) {
social.init(srv, core);
getFeatures(social.getClass(), features);
}
core.init(srv);
features = new HashSet<>();
getFeatures(core.getClass(), features);
if (social != null) {
social.init(srv, core);
getFeatures(social.getClass(), features);
}
}
@ -106,19 +85,7 @@ public final void link(LaunchServer srv) {
if (pair == null) {
throw new NullPointerException(String.format("Auth %s link failed. Pair %s not found", name, v));
}
if ("provider".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 ("core".equals(k)) {
if (pair.core == null)
throw new NullPointerException(String.format("Auth %s link failed. %s.core is null", name, v));
core = pair.core;
@ -130,26 +97,13 @@ public final void close() throws IOException {
if (social != null) {
social.close();
}
if (core == null) {
provider.close();
handler.close();
} else {
core.close();
}
core.close();
if (textureProvider != null) {
textureProvider.close();
}
}
public final boolean isUseCore() {
return core != null;
}
public final boolean isUseSocial() {
return core != null && social != null;
}
public final boolean isUseProviderAndHandler() {
return !isUseCore();
}
}

View file

@ -1,5 +0,0 @@
package pro.gravit.launchserver.auth;
@Deprecated
public interface RequiredDAO {
}

View file

@ -145,13 +145,13 @@ public void invoke(String... args) throws Exception {
return;
}
if (report.isUsingOAuth()) {
logger.info("OAuth: AccessToken: {} RefreshToken: {} MinecraftAccessToken: {}", report.oauthAccessToken, report.oauthRefreshToken, report.minecraftAccessToken);
if (report.session != null) {
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("OAuth: AccessToken: {} RefreshToken: {} MinecraftAccessToken: {}", report.oauthAccessToken(), report.oauthRefreshToken(), report.minecraftAccessToken());
if (report.session() != null) {
logger.info("UserSession: id {} expire {} user {}", report.session().getID(), report.session().getExpireIn(), report.session().getUser() == null ? "null" : "found");
logger.info(report.session().toString());
}
} else {
logger.info("Basic: MinecraftAccessToken: {}", report.minecraftAccessToken);
logger.info("Basic: MinecraftAccessToken: {}", report.minecraftAccessToken());
}
}
});

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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() {
}
}

View file

@ -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;
}
}

View file

@ -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
}
}

View file

@ -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);
}
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}
}

View file

@ -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() {
}
}

View file

@ -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
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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");
}
}

View file

@ -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() {
}
}

View file

@ -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;
}
}
}

View file

@ -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();
}
}

View file

@ -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;
}
}

View file

@ -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();
}
}

View file

@ -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;
}
}

View file

@ -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));
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -1,9 +1,6 @@
package pro.gravit.launchserver.command.handler;
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.RestartCommand;
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");
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
BaseCommandCategory service = new BaseCommandCategory();
service.registerCommand("config", new ConfigCommand(server));

View file

@ -4,11 +4,9 @@
import org.apache.logging.log4j.Logger;
import pro.gravit.launcher.profiles.ClientProfile;
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.NoProtectHandler;
import pro.gravit.launchserver.auth.protect.StdProtectHandler;
import pro.gravit.launchserver.auth.provider.AcceptAuthProvider;
import pro.gravit.launchserver.command.Command;
import pro.gravit.launchserver.components.ProGuardComponent;
import pro.gravit.launchserver.config.LaunchServerConfig;
@ -68,19 +66,6 @@ public String getUsageDescription() {
public void invoke(String... args) {
LaunchServerConfig config = server.config;
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) {
printCheckResult("protectHandler", "protectHandler none", false);

View file

@ -4,7 +4,6 @@
import org.apache.logging.log4j.Logger;
import pro.gravit.launchserver.LaunchServer;
import pro.gravit.launchserver.auth.AuthProviderPair;
import pro.gravit.launchserver.auth.handler.CachedAuthHandler;
import pro.gravit.launchserver.command.Command;
import pro.gravit.utils.command.CommandHandler;
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);
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());
}
}
}

View file

@ -19,7 +19,6 @@
import pro.gravit.launchserver.components.Component;
import pro.gravit.launchserver.components.ProGuardComponent;
import pro.gravit.launchserver.components.RegLimiterComponent;
import pro.gravit.launchserver.dao.provider.DaoProvider;
import pro.gravit.utils.Version;
import pro.gravit.utils.helper.JVMHelper;
@ -37,8 +36,6 @@ public final class LaunchServerConfig {
public boolean cacheUpdates = true;
public LauncherConfig.LauncherEnvironment env;
public Map<String, AuthProviderPair> auth;
@Deprecated
public DaoProvider dao;
public SessionStorage sessions;
// Handlers & Providers
public ProtectHandler protectHandler;
@ -154,10 +151,6 @@ public void verify() {
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;
for (AuthProviderPair pair : auth.values()) {
if (pair.isDefault) {
@ -183,13 +176,6 @@ public void init(LaunchServer.ReloadType type) {
Launcher.applyLauncherEnv(env);
for (Map.Entry<String, AuthProviderPair> provider : auth.entrySet()) {
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) {
server.registerObject("protectHandler", protectHandler);
@ -205,8 +191,6 @@ public void init(LaunchServer.ReloadType type) {
}
if (!type.equals(LaunchServer.ReloadType.NO_AUTH)) {
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(".social"), pair.social);
server.registerObject("auth.".concat(pair.name).concat(".texture"), pair.textureProvider);
@ -219,8 +203,6 @@ public void close(LaunchServer.ReloadType type) {
try {
if (!type.equals(LaunchServer.ReloadType.NO_AUTH)) {
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(".core"), pair.core);
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 {

View file

@ -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);
}

View file

@ -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();
}

View file

@ -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);
}

View file

@ -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();
}
}

View file

@ -16,9 +16,6 @@
import pro.gravit.launchserver.auth.core.User;
import pro.gravit.launchserver.auth.core.UserSession;
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.socket.Client;
import pro.gravit.launchserver.socket.response.auth.AuthResponse;
@ -61,12 +58,10 @@ public AuthResponse.AuthContext makeAuthContext(Client client, AuthResponse.Conn
*/
public void check(AuthResponse.AuthContext context) throws AuthException {
if (context.authType == AuthResponse.ConnectTypes.CLIENT && !context.client.checkSign) {
AuthProvider.authError("Don't skip Launcher Update");
return;
throw new AuthException("Don't skip Launcher Update");
}
if (context.client.isAuth) {
AuthProvider.authError("You are already logged in");
return;
throw new AuthException("You are already logged in");
}
}
@ -78,43 +73,6 @@ public void check(AuthResponse.AuthContext context) throws AuthException {
* @return Access token
*/
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;
provider.verifyAuth(context);
if (password instanceof AuthOAuthPassword password1) {
@ -203,30 +161,19 @@ public void internalAuth(Client client, AuthResponse.ConnectTypes authType, Auth
client.type = authType;
client.uuid = uuid;
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 {
if (client.auth == null) return null;
if (client.auth.isUseCore()) {
User user = client.auth.core.checkServer(client, username, serverID);
if (user == null) return null;
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));
}
User user = client.auth.core.checkServer(client, username, serverID);
if (user == null) return null;
else return CheckServerReport.ofUser(user, getPlayerProfile(client.auth, user));
}
public boolean joinServer(Client client, String username, String accessToken, String serverID) throws IOException {
if (client.auth == null) return false;
if (client.auth.isUseCore()) {
return client.auth.core.joinServer(client, username, accessToken, serverID);
} else {
return client.auth.handler.joinServer(username, accessToken, serverID);
}
return client.auth.core.joinServer(client, username, accessToken, serverID);
}
public PlayerProfile getPlayerProfile(Client client) {
@ -252,22 +199,14 @@ public PlayerProfile getPlayerProfile(AuthProviderPair pair, String username) {
}
public PlayerProfile getPlayerProfile(AuthProviderPair pair, String username, ClientProfile profile) {
UUID uuid = null;
if (pair.isUseCore()) {
User user = pair.core.getUserByUsername(username);
if (user == null) {
return null;
}
PlayerProfile playerProfile = getPlayerProfile(pair, user);
uuid = user.getUUID();
if (playerProfile != null) return playerProfile;
} else {
try {
uuid = pair.handler.usernameToUUID(username);
} catch (IOException e) {
logger.error("UsernameToUUID failed", e);
}
UUID uuid;
User user = pair.core.getUserByUsername(username);
if (user == null) {
return null;
}
PlayerProfile playerProfile = getPlayerProfile(pair, user);
uuid = user.getUUID();
if (playerProfile != null) return playerProfile;
if (uuid == null) {
return null;
}
@ -282,22 +221,14 @@ public PlayerProfile getPlayerProfile(AuthProviderPair pair, UUID uuid) {
}
public PlayerProfile getPlayerProfile(AuthProviderPair pair, UUID uuid, ClientProfile profile) {
String username = null;
if (pair.isUseCore()) {
User user = pair.core.getUserByUUID(uuid);
if (user == null) {
return null;
}
PlayerProfile playerProfile = getPlayerProfile(pair, user);
username = user.getUsername();
if (playerProfile != null) return playerProfile;
} else {
try {
username = pair.handler.uuidToUsername(uuid);
} catch (IOException e) {
logger.error("UUIDToUsername failed", e);
}
String username;
User user = pair.core.getUserByUUID(uuid);
if (user == null) {
return null;
}
PlayerProfile playerProfile = getPlayerProfile(pair, user);
username = user.getUsername();
if (playerProfile != null) return playerProfile;
if (username == null) {
return null;
}
@ -392,20 +323,9 @@ public static CheckServerReport ofUUID(UUID uuid, PlayerProfile playerProfile) {
}
}
public static class AuthReport {
public final String minecraftAccessToken;
public final String oauthAccessToken;
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 record AuthReport(String minecraftAccessToken, String oauthAccessToken,
String oauthRefreshToken, long oauthExpire,
UserSession session) {
public static AuthReport ofOAuth(String oauthAccessToken, String oauthRefreshToken, long oauthExpire) {
return new AuthReport(null, oauthAccessToken, oauthRefreshToken, oauthExpire, null);

View file

@ -11,15 +11,12 @@
import pro.gravit.launcher.request.auth.AuthRequest;
import pro.gravit.launcher.request.auth.GetAvailabilityAuthRequest;
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.protect.ProtectHandler;
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.texture.TextureProvider;
import pro.gravit.launchserver.components.Component;
import pro.gravit.launchserver.dao.provider.DaoProvider;
import pro.gravit.launchserver.modules.impl.LaunchServerModulesManager;
import pro.gravit.launchserver.socket.WebSocketService;
import pro.gravit.launchserver.socket.response.UnknownResponse;
@ -34,17 +31,13 @@ public LaunchServerGsonManager(LaunchServerModulesManager modulesManager) {
}
@Override
@SuppressWarnings("deprecation")
public void registerAdapters(GsonBuilder builder) {
super.registerAdapters(builder);
builder.registerTypeAdapter(AuthProvider.class, new UniversalJsonAdapter<>(AuthProvider.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(PasswordVerifier.class, new UniversalJsonAdapter<>(PasswordVerifier.providers));
builder.registerTypeAdapter(Component.class, new UniversalJsonAdapter<>(Component.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(WebSocketEvent.class, new JsonResultSerializeAdapter());
builder.registerTypeAdapter(AuthRequest.AuthPasswordInterface.class, new UniversalJsonAdapter<>(AuthRequest.providers));

View file

@ -3,7 +3,6 @@
import pro.gravit.launcher.Launcher;
import pro.gravit.launcher.NeedGarbageCollection;
import pro.gravit.launchserver.LaunchServer;
import pro.gravit.launchserver.auth.RequiredDAO;
import pro.gravit.launchserver.socket.Client;
import pro.gravit.utils.HookSet;
import pro.gravit.utils.helper.IOHelper;
@ -53,18 +52,11 @@ private Client decompressClient(byte[] client) {
return Launcher.gsonManager.gson.fromJson(IOHelper.decode(client), Client.class); //Compress using later
}
@SuppressWarnings("deprecation")
private Client restoreFromString(byte[] data) {
Client result = decompressClient(data);
result.updateAuth(server);
if (result.auth != null && (result.username != null)) {
if (result.auth.isUseCore()) {
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);
}
}
result.coreObject = result.auth.core.getUserByUUID(result.uuid);
}
if (result.refCount == null) result.refCount = new AtomicInteger(1);
clientRestoreHook.hook(result);

View file

@ -5,7 +5,6 @@
import pro.gravit.launcher.request.secure.HardwareReportRequest;
import pro.gravit.launchserver.LaunchServer;
import pro.gravit.launchserver.auth.AuthProviderPair;
import pro.gravit.launchserver.dao.User;
import pro.gravit.launchserver.socket.response.auth.AuthResponse;
import java.util.HashMap;
@ -29,9 +28,6 @@ public class Client {
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.UserSession sessionObject;
@ -86,7 +82,7 @@ public void setSerializableProperty(String name, String value) {
public pro.gravit.launchserver.auth.core.User getUser() {
if (coreObject != null) return coreObject;
if (auth != null && uuid != null && auth.isUseCore()) {
if (auth != null && uuid != null) {
coreObject = auth.core.getUserByUUID(uuid);
}
return coreObject;

View file

@ -16,7 +16,6 @@
import pro.gravit.launcher.events.request.ExitRequestEvent;
import pro.gravit.launcher.request.WebSocketEvent;
import pro.gravit.launchserver.LaunchServer;
import pro.gravit.launchserver.dao.User;
import pro.gravit.launchserver.socket.handlers.WebSocketFrameHandler;
import pro.gravit.launchserver.socket.response.SimpleResponse;
import pro.gravit.launchserver.socket.response.WebSocketServerResponse;
@ -43,7 +42,6 @@
import java.util.UUID;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
public class WebSocketService {
public static final ProviderMap<WebSocketServerResponse> providers = new ProviderMap<>();
@ -222,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) {
for (Channel ch : channels) {
if (ch == null || ch.pipeline() == null) continue;

View file

@ -23,7 +23,7 @@ public String getType() {
@Override
public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
if (!client.isAuth || !client.auth.isUseCore()) {
if (!client.isAuth) {
sendError("Access denied");
return;
}

View file

@ -48,7 +48,7 @@ public void execute(ChannelHandlerContext ctx, Client clientData) throws Excepti
context.report = server.authManager.auth(context, password);
server.authHookManager.postHook.hook(context, clientData);
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) {
if (clientData.session == null) {
clientData.session = UUID.randomUUID();
@ -56,8 +56,8 @@ public void execute(ChannelHandlerContext ctx, Client clientData) throws Excepti
}
result.session = clientData.session;
}
if (context.report.minecraftAccessToken != null) {
result.accessToken = context.report.minecraftAccessToken;
if (context.report.minecraftAccessToken() != null) {
result.accessToken = context.report.minecraftAccessToken();
}
result.playerProfile = server.authManager.getPlayerProfile(clientData);
sendResult(result);

View file

@ -5,24 +5,10 @@
import pro.gravit.launchserver.LaunchServer;
import pro.gravit.launchserver.socket.Client;
import pro.gravit.launchserver.socket.response.SimpleResponse;
import pro.gravit.launchserver.socket.response.profile.ProfileByUUIDResponse;
import java.io.IOException;
import java.util.UUID;
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 {
CurrentUserRequestEvent.UserInfo result = new CurrentUserRequestEvent.UserInfo();

View file

@ -19,7 +19,8 @@ public String getType() {
public void execute(ChannelHandlerContext ctx, Client client) {
List<GetAvailabilityAuthRequestEvent.AuthAvailability> list = new ArrayList<>();
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));
}

View file

@ -33,7 +33,7 @@ public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
} else {
pair = client.auth;
}
if (pair == null || !pair.isUseCore()) {
if (pair == null) {
sendError("Invalid request");
return;
}
@ -42,6 +42,6 @@ public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
sendError("Invalid RefreshToken");
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())));
}
}

View file

@ -57,7 +57,7 @@ public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
} else {
pair = client.auth;
}
if (pair == null || !pair.isUseCore()) {
if (pair == null) {
sendError("Invalid authId");
return;
}

View file

@ -46,7 +46,6 @@ public String getType() {
@Override
public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
String username;
AuthProviderPair pair;
if (client.auth == null) {
pair = server.config.getAuthProviderPair();
@ -57,18 +56,10 @@ public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
sendError("ProfileByUUIDResponse: AuthProviderPair is null");
return;
}
if (pair.isUseCore()) {
User user = pair.core.getUserByUUID(uuid);
if (user == null) {
sendError("User not found");
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;
}
User user = pair.core.getUserByUUID(uuid);
if (user == null) {
sendError("User not found");
return;
}
sendResult(new ProfileByUUIDRequestEvent(server.authManager.getPlayerProfile(pair, uuid)));
}

View file

@ -2,18 +2,8 @@
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import pro.gravit.launcher.ClientPermissions;
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.LaunchServerRuntimeConfig;
import pro.gravit.launchserver.impl.TestLaunchServerConfigManager;
@ -21,9 +11,7 @@
import pro.gravit.launchserver.manangers.LaunchServerGsonManager;
import pro.gravit.launchserver.modules.impl.LaunchServerModulesManager;
import pro.gravit.utils.command.StdCommandHandler;
import pro.gravit.utils.helper.SecurityHelper;
import java.io.IOException;
import java.nio.file.Path;
import java.security.Security;
@ -57,26 +45,4 @@ public static void prepare() throws Throwable {
.setCommandHandler(new StdCommandHandler(false));
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);
}
}

View file

@ -6,9 +6,9 @@ public final class Version implements Comparable<Version> {
public static final int MAJOR = 5;
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 Version.Type RELEASE = Type.STABLE;
public static final Version.Type RELEASE = Type.DEV;
public final int major;
public final int minor;
public final int patch;