forked from TuxCoding/FastLogin
Add support for postgresql
This commit is contained in:
@ -117,10 +117,10 @@ Install the plugin on both platforms, that is proxy (BungeeCord or Velocity) and
|
||||
4. Activate ip forwarding in your proxy config
|
||||
5. Check your database settings in the config of FastLogin on your proxy
|
||||
* The proxies only ship with a limited set of drivers where Spigot supports more. Therefore, these are supported:
|
||||
* BungeeCord: `com.mysql.jdbc.Driver` for MySQL/MariaDB
|
||||
* Velocity: `fastlogin.mariadb.jdbc.Driver` for MySQL/MariaDB
|
||||
* BungeeCord: `com.mysql.jdbc.Driver` for MySQL/MariaDB/PostgreSQL
|
||||
* Velocity: `fastlogin.mariadb.jdbc.Driver` for MySQL/MariaDB/PostgreSQL
|
||||
* Note the embedded file storage SQLite is not available
|
||||
* MySQL/MariaDB requires an external database server running. Check your server provider if there is one available
|
||||
* MySQL/MariaDB/PostgreSQL requires an external database server running. Check your server provider if there is one available
|
||||
or install one.
|
||||
6. Set proxy and Spigot in offline mode by setting the value `onlinemode` in your `config.yml` to false
|
||||
7. You should *always* configure the firewall for your Spigot server so that it's only accessible through your proxy
|
||||
|
@ -36,6 +36,7 @@ import com.github.games647.fastlogin.core.antibot.TickingRateLimiter;
|
||||
import com.github.games647.fastlogin.core.hooks.AuthPlugin;
|
||||
import com.github.games647.fastlogin.core.hooks.DefaultPasswordGenerator;
|
||||
import com.github.games647.fastlogin.core.hooks.PasswordGenerator;
|
||||
import com.github.games647.fastlogin.core.storage.PostgreSQLStorage;
|
||||
import com.github.games647.fastlogin.core.storage.MySQLStorage;
|
||||
import com.github.games647.fastlogin.core.storage.SQLStorage;
|
||||
import com.github.games647.fastlogin.core.storage.SQLiteStorage;
|
||||
@ -230,6 +231,24 @@ public class FastLoginCore<P extends C, C, T extends PlatformPlugin<C>> {
|
||||
|
||||
if (type.contains("sqlite")) {
|
||||
storage = new SQLiteStorage(plugin, database, databaseConfig);
|
||||
} else if (type.contains("postgresql")) {
|
||||
String host = config.get("host", "");
|
||||
int port = config.get("port", 3306);
|
||||
boolean useSSL = config.get("useSSL", false);
|
||||
|
||||
if (useSSL) {
|
||||
boolean publicKeyRetrieval = config.getBoolean("allowPublicKeyRetrieval", false);
|
||||
String rsaPublicKeyFile = config.getString("ServerRSAPublicKeyFile");
|
||||
String sslMode = config.getString("sslMode", "Required");
|
||||
|
||||
databaseConfig.addDataSourceProperty("allowPublicKeyRetrieval", publicKeyRetrieval);
|
||||
databaseConfig.addDataSourceProperty("serverRSAPublicKeyFile", rsaPublicKeyFile);
|
||||
databaseConfig.addDataSourceProperty("sslMode", sslMode);
|
||||
}
|
||||
|
||||
databaseConfig.setUsername(config.get("username", ""));
|
||||
databaseConfig.setPassword(config.getString("password"));
|
||||
storage = new PostgreSQLStorage(plugin, type, host, port, database, databaseConfig, useSSL);
|
||||
} else {
|
||||
String host = config.get("host", "");
|
||||
int port = config.get("port", 3306);
|
||||
|
@ -0,0 +1,101 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015-2023 games647 and contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
package com.github.games647.fastlogin.core.storage;
|
||||
|
||||
import com.github.games647.fastlogin.core.shared.PlatformPlugin;
|
||||
import com.zaxxer.hikari.HikariConfig;
|
||||
|
||||
public class PostgreSQLStorage extends SQLStorage {
|
||||
|
||||
private static final String JDBC_PROTOCOL = "jdbc:";
|
||||
|
||||
public PostgreSQLStorage(PlatformPlugin<?> plugin, String driver, String host, int port, String database,
|
||||
HikariConfig config, boolean useSSL) {
|
||||
super(plugin.getLog(), plugin.getName(), plugin.getThreadFactory(),
|
||||
setParams(config, driver, host, port, database, useSSL));
|
||||
}
|
||||
|
||||
private static HikariConfig setParams(HikariConfig config,
|
||||
String driver, String host, int port, String database,
|
||||
boolean useSSL) {
|
||||
// Require SSL on the server if requested in config - this will also verify certificate
|
||||
// Those values are deprecated in favor of sslMode
|
||||
config.addDataSourceProperty("useSSL", useSSL);
|
||||
config.addDataSourceProperty("requireSSL", useSSL);
|
||||
|
||||
// adding paranoid, hides hostname, username, version and so
|
||||
// could be useful for hiding server details
|
||||
config.addDataSourceProperty("paranoid", true);
|
||||
|
||||
config.setJdbcUrl(JDBC_PROTOCOL + buildJDBCUrl(driver, host, port, database));
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
private static String buildJDBCUrl(String driver, String host, int port, String database) {
|
||||
return "postgresql://" + host + ':' + port + '/' + database;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getCreateTableStmt() {
|
||||
// PostgreSQL has a different syntax for id column
|
||||
return CREATE_TABLE_STMT
|
||||
.replace("`", "\"")
|
||||
.replace("INTEGER PRIMARY KEY AUTO_INCREMENT", "SERIAL PRIMARY KEY");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getAddFloodgateColumnStmt() {
|
||||
// PostgreSQL has a different syntax
|
||||
return ADD_FLOODGATE_COLUMN_STMT
|
||||
.replace("`", "\"")
|
||||
.replace("INTEGER(3)", "INTEGER");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getLoadByNameStmt() {
|
||||
return LOAD_BY_NAME_STMT
|
||||
.replace("`", "\"");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getLoadByUuidStmt() {
|
||||
return LOAD_BY_UUID_STMT
|
||||
.replace("`", "\"");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getInsertProfileStmt() {
|
||||
return INSERT_PROFILE_STMT
|
||||
.replace("`", "\"");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getUpdateProfileStmt() {
|
||||
return UPDATE_PROFILE_STMT
|
||||
.replace("`", "\"");
|
||||
}
|
||||
}
|
@ -61,14 +61,14 @@ public abstract class SQLStorage implements AuthStorage {
|
||||
protected static final String ADD_FLOODGATE_COLUMN_STMT = "ALTER TABLE `" + PREMIUM_TABLE
|
||||
+ "` ADD COLUMN `Floodgate` INTEGER(3)";
|
||||
|
||||
protected static final String LOAD_BY_NAME = "SELECT * FROM `" + PREMIUM_TABLE
|
||||
protected static final String LOAD_BY_NAME_STMT = "SELECT * FROM `" + PREMIUM_TABLE
|
||||
+ "` WHERE `Name`=? LIMIT 1";
|
||||
protected static final String LOAD_BY_UUID = "SELECT * FROM `" + PREMIUM_TABLE
|
||||
protected static final String LOAD_BY_UUID_STMT = "SELECT * FROM `" + PREMIUM_TABLE
|
||||
+ "` WHERE `UUID`=? LIMIT 1";
|
||||
protected static final String INSERT_PROFILE = "INSERT INTO `" + PREMIUM_TABLE
|
||||
protected static final String INSERT_PROFILE_STMT = "INSERT INTO `" + PREMIUM_TABLE
|
||||
+ "` (`UUID`, `Name`, `Premium`, `Floodgate`, `LastIp`) " + "VALUES (?, ?, ?, ?, ?) ";
|
||||
// limit not necessary here, because it's unique
|
||||
protected static final String UPDATE_PROFILE = "UPDATE `" + PREMIUM_TABLE
|
||||
protected static final String UPDATE_PROFILE_STMT = "UPDATE `" + PREMIUM_TABLE
|
||||
+ "` SET `UUID`=?, `Name`=?, `Premium`=?, `Floodgate`=?, `LastIp`=?, "
|
||||
+ "`LastLogin`=CURRENT_TIMESTAMP WHERE `UserID`=?";
|
||||
|
||||
@ -97,7 +97,7 @@ public abstract class SQLStorage implements AuthStorage {
|
||||
// add Floodgate column
|
||||
DatabaseMetaData md = con.getMetaData();
|
||||
if (isColumnMissing(md, "Floodgate")) {
|
||||
stmt.executeUpdate(ADD_FLOODGATE_COLUMN_STMT);
|
||||
stmt.executeUpdate(getAddFloodgateColumnStmt());
|
||||
}
|
||||
|
||||
}
|
||||
@ -112,7 +112,7 @@ public abstract class SQLStorage implements AuthStorage {
|
||||
@Override
|
||||
public StoredProfile loadProfile(String name) {
|
||||
try (Connection con = dataSource.getConnection();
|
||||
PreparedStatement loadStmt = con.prepareStatement(LOAD_BY_NAME)
|
||||
PreparedStatement loadStmt = con.prepareStatement(getLoadByNameStmt())
|
||||
) {
|
||||
loadStmt.setString(1, name);
|
||||
|
||||
@ -130,7 +130,7 @@ public abstract class SQLStorage implements AuthStorage {
|
||||
@Override
|
||||
public StoredProfile loadProfile(UUID uuid) {
|
||||
try (Connection con = dataSource.getConnection();
|
||||
PreparedStatement loadStmt = con.prepareStatement(LOAD_BY_UUID)) {
|
||||
PreparedStatement loadStmt = con.prepareStatement(getLoadByUuidStmt())) {
|
||||
loadStmt.setString(1, UUIDAdapter.toMojangId(uuid));
|
||||
|
||||
try (ResultSet resultSet = loadStmt.executeQuery()) {
|
||||
@ -177,7 +177,7 @@ public abstract class SQLStorage implements AuthStorage {
|
||||
playerProfile.getSaveLock().lock();
|
||||
try {
|
||||
if (playerProfile.isSaved()) {
|
||||
try (PreparedStatement saveStmt = con.prepareStatement(UPDATE_PROFILE)) {
|
||||
try (PreparedStatement saveStmt = con.prepareStatement(getUpdateProfileStmt())) {
|
||||
saveStmt.setString(1, uuid);
|
||||
saveStmt.setString(2, playerProfile.getName());
|
||||
saveStmt.setBoolean(3, playerProfile.isPremium());
|
||||
@ -188,7 +188,8 @@ public abstract class SQLStorage implements AuthStorage {
|
||||
saveStmt.execute();
|
||||
}
|
||||
} else {
|
||||
try (PreparedStatement saveStmt = con.prepareStatement(INSERT_PROFILE, RETURN_GENERATED_KEYS)) {
|
||||
try (PreparedStatement saveStmt = con.prepareStatement(getInsertProfileStmt(),
|
||||
RETURN_GENERATED_KEYS)) {
|
||||
saveStmt.setString(1, uuid);
|
||||
|
||||
saveStmt.setString(2, playerProfile.getName());
|
||||
@ -214,13 +215,37 @@ public abstract class SQLStorage implements AuthStorage {
|
||||
}
|
||||
|
||||
/**
|
||||
* SQLite has a slightly different syntax, so this will be overridden by SQLiteStorage
|
||||
* SQLite and PostgreSQL have a slightly different syntax, so this will be overridden by SQLiteStorage and so on...
|
||||
* @return An SQL Statement to create the `premium` table
|
||||
*/
|
||||
protected String getCreateTableStmt() {
|
||||
return CREATE_TABLE_STMT;
|
||||
}
|
||||
|
||||
/**
|
||||
* PostgreSQL has a slightly different syntax, so this will be overridden by PostgreSQLStorage
|
||||
* @return An SQL Statement to create the `premium` table
|
||||
*/
|
||||
protected String getAddFloodgateColumnStmt() {
|
||||
return ADD_FLOODGATE_COLUMN_STMT;
|
||||
}
|
||||
|
||||
protected String getLoadByNameStmt() {
|
||||
return LOAD_BY_NAME_STMT;
|
||||
}
|
||||
|
||||
protected String getLoadByUuidStmt() {
|
||||
return LOAD_BY_UUID_STMT;
|
||||
}
|
||||
|
||||
protected String getInsertProfileStmt() {
|
||||
return INSERT_PROFILE_STMT;
|
||||
}
|
||||
|
||||
protected String getUpdateProfileStmt() {
|
||||
return UPDATE_PROFILE_STMT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
dataSource.close();
|
||||
|
@ -289,6 +289,15 @@ database: '{pluginDir}/FastLogin.db'
|
||||
#username: 'myUser'
|
||||
#password: 'myPassword'
|
||||
|
||||
# PostgreSQL
|
||||
# If you want to enable it, uncomment only the lines below; this not this line.
|
||||
#driver: 'postgresql'
|
||||
#host: '127.0.0.1'
|
||||
#port: 5432
|
||||
#database: 'fastlogin'
|
||||
#username: 'myUser'
|
||||
#password: 'myPassword'
|
||||
|
||||
# Advanced Connection Pool settings in seconds
|
||||
#timeout: 30
|
||||
#lifetime: 30
|
||||
|
Reference in New Issue
Block a user