mirror of
https://github.com/GravitLauncher/Launcher
synced 2024-12-23 00:51:01 +03:00
[FEATURE] Postgresql support
This commit is contained in:
parent
3b8a01fbb4
commit
796b2e2533
4 changed files with 277 additions and 10 deletions
|
@ -5,6 +5,7 @@
|
||||||
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.MySQLCoreProvider;
|
import pro.gravit.launchserver.auth.core.MySQLCoreProvider;
|
||||||
|
import pro.gravit.launchserver.auth.core.PostgresSQLCoreProvider;
|
||||||
import pro.gravit.launchserver.auth.texture.TextureProvider;
|
import pro.gravit.launchserver.auth.texture.TextureProvider;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -39,7 +40,7 @@ public static Set<String> getFeatures(Class<?> clazz) {
|
||||||
|
|
||||||
public void internalShowOAuthWarnMessage() {
|
public void internalShowOAuthWarnMessage() {
|
||||||
if(!warnOAuthShow) {
|
if(!warnOAuthShow) {
|
||||||
if(!(core instanceof MySQLCoreProvider)) { // MySQL upgraded later
|
if(!(core instanceof MySQLCoreProvider) && !(core instanceof PostgresSQLCoreProvider)) { // MySQL and PostgreSQL upgraded later
|
||||||
logger.warn("AuthCoreProvider {} ({}) not supported OAuth. Legacy session system may be removed in next release", name, core.getClass().getName());
|
logger.warn("AuthCoreProvider {} ({}) not supported OAuth. Legacy session system may be removed in next release", name, core.getClass().getName());
|
||||||
}
|
}
|
||||||
warnOAuthShow = true;
|
warnOAuthShow = true;
|
||||||
|
|
|
@ -43,6 +43,7 @@ public static void registerProviders() {
|
||||||
if (!registredProviders) {
|
if (!registredProviders) {
|
||||||
providers.register("reject", RejectAuthCoreProvider.class);
|
providers.register("reject", RejectAuthCoreProvider.class);
|
||||||
providers.register("mysql", MySQLCoreProvider.class);
|
providers.register("mysql", MySQLCoreProvider.class);
|
||||||
|
providers.register("postgresql", PostgresSQLCoreProvider.class);
|
||||||
providers.register("memory", MemoryAuthCoreProvider.class);
|
providers.register("memory", MemoryAuthCoreProvider.class);
|
||||||
providers.register("http", HttpAuthCoreProvider.class);
|
providers.register("http", HttpAuthCoreProvider.class);
|
||||||
registredProviders = true;
|
registredProviders = true;
|
||||||
|
|
|
@ -0,0 +1,265 @@
|
||||||
|
package pro.gravit.launchserver.auth.core;
|
||||||
|
|
||||||
|
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.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.launchserver.auth.PostgreSQLSourceConfig;
|
||||||
|
import pro.gravit.launchserver.auth.password.PasswordVerifier;
|
||||||
|
import pro.gravit.launchserver.manangers.AuthManager;
|
||||||
|
import pro.gravit.launchserver.socket.response.auth.AuthResponse;
|
||||||
|
import pro.gravit.utils.helper.SecurityHelper;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.sql.*;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class PostgresSQLCoreProvider extends AuthCoreProvider {
|
||||||
|
private transient final Logger logger = LogManager.getLogger();
|
||||||
|
public PostgreSQLSourceConfig postgresSQLHolder;
|
||||||
|
|
||||||
|
public String uuidColumn;
|
||||||
|
public String usernameColumn;
|
||||||
|
public String accessTokenColumn;
|
||||||
|
public String passwordColumn;
|
||||||
|
public String serverIDColumn;
|
||||||
|
public String hardwareIdColumn;
|
||||||
|
public String table;
|
||||||
|
|
||||||
|
public PasswordVerifier passwordVerifier;
|
||||||
|
public String customQueryByUUIDSQL;
|
||||||
|
public String customQueryByUsernameSQL;
|
||||||
|
public String customQueryByLoginSQL;
|
||||||
|
public String customUpdateAuthSQL;
|
||||||
|
public String customUpdateServerIdSQL;
|
||||||
|
// Prepared SQL queries
|
||||||
|
private transient String queryByUUIDSQL;
|
||||||
|
private transient String queryByUsernameSQL;
|
||||||
|
private transient String queryByLoginSQL;
|
||||||
|
private transient String updateAuthSQL;
|
||||||
|
private transient String updateServerIDSQL;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public User getUserByUsername(String username) {
|
||||||
|
try {
|
||||||
|
return query(queryByUsernameSQL, username);
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.error("SQL error", e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public User getUserByUUID(UUID uuid) {
|
||||||
|
try {
|
||||||
|
return query(queryByUUIDSQL, uuid.toString());
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.error("SQL error", e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public User getUserByLogin(String login) {
|
||||||
|
try {
|
||||||
|
return query(queryByLoginSQL, login);
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.error("SQL error", e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UserSession getUserSessionByOAuthAccessToken(String accessToken) throws OAuthAccessTokenExpired {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AuthManager.AuthReport refreshAccessToken(String refreshToken, AuthResponse.AuthContext context) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AuthManager.AuthReport authorize(String login, AuthResponse.AuthContext context, AuthRequest.AuthPasswordInterface password, boolean minecraftAccess) throws IOException {
|
||||||
|
PostgresSQLUser postgresSQLUser = (PostgresSQLUser) getUserByLogin(login);
|
||||||
|
if(postgresSQLUser == null) {
|
||||||
|
throw AuthException.wrongPassword();
|
||||||
|
}
|
||||||
|
if(context != null) {
|
||||||
|
AuthPlainPassword plainPassword = (AuthPlainPassword) password;
|
||||||
|
if(plainPassword == null) {
|
||||||
|
throw AuthException.wrongPassword();
|
||||||
|
}
|
||||||
|
if(!passwordVerifier.check(postgresSQLUser.password, plainPassword.password)) {
|
||||||
|
throw AuthException.wrongPassword();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MySQLUserSession session = new MySQLUserSession(postgresSQLUser);
|
||||||
|
if (minecraftAccess) {
|
||||||
|
String minecraftAccessToken = SecurityHelper.randomStringToken();
|
||||||
|
updateAuth(postgresSQLUser, minecraftAccessToken);
|
||||||
|
return AuthManager.AuthReport.ofMinecraftAccessToken(minecraftAccessToken, session);
|
||||||
|
} else {
|
||||||
|
return AuthManager.AuthReport.ofMinecraftAccessToken(null, session);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(LaunchServer server) {
|
||||||
|
if (postgresSQLHolder == null) logger.error("postgresSQLHolder 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 (hardwareIdColumn == null) logger.error("hardwareIdColumn cannot be null");
|
||||||
|
if (table == null) logger.error("table cannot be null");
|
||||||
|
// Prepare SQL queries
|
||||||
|
String userInfoCols = String.format("%s, %s, %s, %s, %s, %s", uuidColumn, usernameColumn, accessTokenColumn, serverIDColumn, passwordColumn, hardwareIdColumn);
|
||||||
|
queryByUUIDSQL = customQueryByUUIDSQL != null ? customQueryByUUIDSQL : String.format("SELECT %s FROM %s WHERE %s=? LIMIT 1", userInfoCols,
|
||||||
|
table, uuidColumn);
|
||||||
|
queryByUsernameSQL = customQueryByUsernameSQL != null ? customQueryByUsernameSQL : String.format("SELECT %s FROM %s WHERE %s=? LIMIT 1",
|
||||||
|
userInfoCols, table, usernameColumn);
|
||||||
|
queryByLoginSQL = customQueryByLoginSQL != null ? customQueryByLoginSQL : queryByUsernameSQL;
|
||||||
|
|
||||||
|
updateAuthSQL = customUpdateAuthSQL != null ? customUpdateAuthSQL : String.format("UPDATE %s SET %s=?, %s=NULL WHERE %s=?",
|
||||||
|
table, accessTokenColumn, serverIDColumn, uuidColumn);
|
||||||
|
updateServerIDSQL = customUpdateServerIdSQL != null ? customUpdateServerIdSQL : String.format("UPDATE %s SET %s=? WHERE %s=?",
|
||||||
|
table, serverIDColumn, uuidColumn);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean updateAuth(User user, String accessToken) throws IOException {
|
||||||
|
try (Connection c = postgresSQLHolder.getConnection()) {
|
||||||
|
PostgresSQLUser postgresSQLUser = (PostgresSQLUser) user;
|
||||||
|
postgresSQLUser.accessToken = accessToken;
|
||||||
|
PreparedStatement s = c.prepareStatement(updateAuthSQL);
|
||||||
|
s.setString(1, accessToken);
|
||||||
|
s.setString(2, user.getUUID().toString());
|
||||||
|
s.setQueryTimeout(MySQLSourceConfig.TIMEOUT);
|
||||||
|
return s.executeUpdate() > 0;
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new IOException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean updateServerID(User user, String serverID) throws IOException {
|
||||||
|
try (Connection c = postgresSQLHolder.getConnection()) {
|
||||||
|
PostgresSQLUser postgresSQLUser = (PostgresSQLUser) user;
|
||||||
|
postgresSQLUser.serverId = serverID;
|
||||||
|
PreparedStatement s = c.prepareStatement(updateServerIDSQL);
|
||||||
|
s.setString(1, serverID);
|
||||||
|
s.setString(2, user.getUUID().toString());
|
||||||
|
s.setQueryTimeout(MySQLSourceConfig.TIMEOUT);
|
||||||
|
return s.executeUpdate() > 0;
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new IOException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws IOException {
|
||||||
|
postgresSQLHolder.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private PostgresSQLUser constructUser(ResultSet set) throws SQLException {
|
||||||
|
return set.next() ? new PostgresSQLUser(UUID.fromString(set.getString(uuidColumn)), set.getString(usernameColumn),
|
||||||
|
set.getString(accessTokenColumn), set.getString(serverIDColumn), set.getString(passwordColumn), new ClientPermissions(), set.getLong(hardwareIdColumn)) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private User query(String sql, String value) throws IOException {
|
||||||
|
try (Connection c = postgresSQLHolder.getConnection()) {
|
||||||
|
PreparedStatement s = c.prepareStatement(sql);
|
||||||
|
s.setString(1, value);
|
||||||
|
s.setQueryTimeout(MySQLSourceConfig.TIMEOUT);
|
||||||
|
try (ResultSet set = s.executeQuery()) {
|
||||||
|
return constructUser(set);
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new IOException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class PostgresSQLUser implements User {
|
||||||
|
protected UUID uuid;
|
||||||
|
protected String username;
|
||||||
|
protected String accessToken;
|
||||||
|
protected String serverId;
|
||||||
|
protected String password;
|
||||||
|
protected ClientPermissions permissions;
|
||||||
|
protected long hwidId;
|
||||||
|
|
||||||
|
public PostgresSQLUser(UUID uuid, String username, String accessToken, String serverId, String password, ClientPermissions permissions, long hwidId) {
|
||||||
|
this.uuid = uuid;
|
||||||
|
this.username = username;
|
||||||
|
this.accessToken = accessToken;
|
||||||
|
this.serverId = serverId;
|
||||||
|
this.password = password;
|
||||||
|
this.permissions = permissions;
|
||||||
|
this.hwidId = hwidId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UUID getUUID() {
|
||||||
|
return uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getServerId() {
|
||||||
|
return serverId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getAccessToken() {
|
||||||
|
return accessToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClientPermissions getPermissions() {
|
||||||
|
return permissions;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "PostgresSQLUser{" +
|
||||||
|
"uuid=" + uuid +
|
||||||
|
", username='" + username + '\'' +
|
||||||
|
", permissions=" + permissions +
|
||||||
|
", hwidId=" + hwidId +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class MySQLUserSession implements UserSession {
|
||||||
|
private final PostgresSQLUser user;
|
||||||
|
private final String id;
|
||||||
|
|
||||||
|
public MySQLUserSession(PostgresSQLUser user) {
|
||||||
|
this.user = user;
|
||||||
|
this.id = user.username;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getID() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public User getUser() {
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getExpireIn() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
18
props.gradle
18
props.gradle
|
@ -1,19 +1,19 @@
|
||||||
project.ext {
|
project.ext {
|
||||||
verAsm = '9.2'
|
verAsm = '9.2'
|
||||||
verNetty = '4.1.68.Final'
|
verNetty = '4.1.70.Final'
|
||||||
verOshiCore = '5.8.0'
|
verOshiCore = '5.8.5'
|
||||||
verJunit = '5.7.2'
|
verJunit = '5.8.2'
|
||||||
verGuavaC = '30.1.1-jre'
|
verGuavaC = '30.1.1-jre'
|
||||||
verJansi = '2.3.4'
|
verJansi = '2.3.4'
|
||||||
verJline = '3.20.0'
|
verJline = '3.21.0'
|
||||||
verJwt = '0.11.2'
|
verJwt = '0.11.2'
|
||||||
verBcprov = '1.69'
|
verBcprov = '1.70'
|
||||||
verGson = '2.8.9'
|
verGson = '2.8.9'
|
||||||
verBcpkix = '1.69'
|
verBcpkix = '1.70'
|
||||||
verSlf4j = '1.7.32'
|
verSlf4j = '1.7.32'
|
||||||
verLog4j = '2.14.1'
|
verLog4j = '2.15.0'
|
||||||
verMySQLConn = '8.0.26'
|
verMySQLConn = '8.0.27'
|
||||||
verPostgreSQLConn = '42.2.24'
|
verPostgreSQLConn = '42.3.1'
|
||||||
verProguard = '7.2.0-beta2'
|
verProguard = '7.2.0-beta2'
|
||||||
verLaunch4j = '3.14'
|
verLaunch4j = '3.14'
|
||||||
verHibernate = '5.5.6.Final'
|
verHibernate = '5.5.6.Final'
|
||||||
|
|
Loading…
Reference in a new issue