mirror of
https://github.com/GravitLauncher/Launcher
synced 2025-01-09 00:59:44 +03:00
[FEATURE] Поддержка PostgreSQL!
This commit is contained in:
parent
884b82deb8
commit
2eb994f313
5 changed files with 241 additions and 0 deletions
|
@ -0,0 +1,81 @@
|
|||
package pro.gravit.launchserver.auth;
|
||||
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
|
||||
import pro.gravit.utils.helper.LogHelper;
|
||||
import pro.gravit.utils.helper.VerifyHelper;
|
||||
|
||||
import org.postgresql.ds.PGSimpleDataSource;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
|
||||
public final class PostgreSQLSourceConfig implements AutoCloseable {
|
||||
public static final int TIMEOUT = VerifyHelper.verifyInt(
|
||||
Integer.parseUnsignedInt(System.getProperty("launcher.postgresql.idleTimeout", Integer.toString(5000))),
|
||||
VerifyHelper.POSITIVE, "launcher.postgresql.idleTimeout can't be <= 5000");
|
||||
private static final int MAX_POOL_SIZE = VerifyHelper.verifyInt(
|
||||
Integer.parseUnsignedInt(System.getProperty("launcher.postgresql.maxPoolSize", Integer.toString(3))),
|
||||
VerifyHelper.POSITIVE, "launcher.postgresql.maxPoolSize can't be <= 0");
|
||||
|
||||
// Instance
|
||||
private String poolName;
|
||||
|
||||
// Config
|
||||
private String address;
|
||||
private int port;
|
||||
private String username;
|
||||
private String password;
|
||||
private String database;
|
||||
|
||||
// Cache
|
||||
private DataSource source;
|
||||
private boolean hikari;
|
||||
|
||||
@Override
|
||||
public synchronized void close() {
|
||||
if (hikari) { // Shutdown hikari pool
|
||||
((HikariDataSource) source).close();
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized Connection getConnection() throws SQLException {
|
||||
if (source == null) { // New data source
|
||||
PGSimpleDataSource postgresqlSource = new PGSimpleDataSource();
|
||||
|
||||
// Set credentials
|
||||
postgresqlSource.setServerName(address);
|
||||
postgresqlSource.setPortNumber(port);
|
||||
postgresqlSource.setUser(username);
|
||||
postgresqlSource.setPassword(password);
|
||||
postgresqlSource.setDatabaseName(database);
|
||||
|
||||
// Try using HikariCP
|
||||
source = postgresqlSource;
|
||||
|
||||
//noinspection Duplicates
|
||||
try {
|
||||
Class.forName("com.zaxxer.hikari.HikariDataSource");
|
||||
hikari = true; // Used for shutdown. Not instanceof because of possible classpath error
|
||||
|
||||
// Set HikariCP pool
|
||||
HikariDataSource hikariSource = new HikariDataSource();
|
||||
hikariSource.setDataSource(source);
|
||||
|
||||
// Set pool settings
|
||||
hikariSource.setPoolName(poolName);
|
||||
hikariSource.setMinimumIdle(0);
|
||||
hikariSource.setMaximumPoolSize(MAX_POOL_SIZE);
|
||||
hikariSource.setIdleTimeout(TIMEOUT * 1000L);
|
||||
|
||||
// Replace source with hds
|
||||
source = hikariSource;
|
||||
LogHelper.info("HikariCP pooling enabled for '%s'", poolName);
|
||||
} catch (ClassNotFoundException ignored) {
|
||||
LogHelper.warning("HikariCP isn't in classpath for '%s'", poolName);
|
||||
}
|
||||
}
|
||||
return source.getConnection();
|
||||
}
|
||||
}
|
|
@ -24,6 +24,7 @@ public static void registerHandlers() {
|
|||
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;
|
||||
|
|
|
@ -0,0 +1,116 @@
|
|||
package pro.gravit.launchserver.auth.handler;
|
||||
|
||||
import org.postgresql.util.PGobject;
|
||||
|
||||
import pro.gravit.launchserver.auth.PostgreSQLSourceConfig;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.*;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -20,6 +20,7 @@ public static void registerProviders() {
|
|||
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);
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
package pro.gravit.launchserver.auth.provider;
|
||||
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import pro.gravit.launcher.ClientPermissions;
|
||||
import pro.gravit.launchserver.auth.AuthException;
|
||||
import pro.gravit.launchserver.auth.PostgreSQLSourceConfig;
|
||||
import pro.gravit.utils.helper.CommonHelper;
|
||||
import pro.gravit.utils.helper.SecurityHelper;
|
||||
|
||||
public final class PostgreSQLAuthProvider extends AuthProvider {
|
||||
private PostgreSQLSourceConfig postgreSQLHolder;
|
||||
private String query;
|
||||
private String message;
|
||||
private String[] queryParams;
|
||||
private boolean usePermission;
|
||||
|
||||
@Override
|
||||
public AuthProviderResult auth(String login, String password, String ip) throws SQLException, AuthException {
|
||||
try (Connection c = postgreSQLHolder.getConnection(); PreparedStatement s = c.prepareStatement(query)) {
|
||||
String[] replaceParams = {"login", login, "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(), usePermission ? new ClientPermissions(set.getLong(2)) : srv.config.permissionsHandler.getPermissions(set.getString(1))) : authError(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue