mirror of
https://github.com/funkemunky/AntiVPN.git
synced 2026-06-01 01:41:55 +00:00
Version 2.0.0-SNAPSHOT: Updated to use SQLLite with versioning. Needed a recode of the database system to allow for future updates.
This commit is contained in:
@@ -6,9 +6,7 @@ import dev.brighten.antivpn.api.VPNExecutor;
|
||||
import dev.brighten.antivpn.command.Command;
|
||||
import dev.brighten.antivpn.command.impl.AntiVPNCommand;
|
||||
import dev.brighten.antivpn.database.VPNDatabase;
|
||||
import dev.brighten.antivpn.database.local.H2VPN;
|
||||
import dev.brighten.antivpn.database.mongo.MongoVPN;
|
||||
import dev.brighten.antivpn.database.sql.MySqlVPN;
|
||||
import dev.brighten.antivpn.database.sqllite.LiteDatabase;
|
||||
import dev.brighten.antivpn.message.MessageHandler;
|
||||
import dev.brighten.antivpn.utils.ConfigDefault;
|
||||
import dev.brighten.antivpn.utils.MiscUtils;
|
||||
@@ -70,35 +68,8 @@ public class AntiVPN {
|
||||
|
||||
INSTANCE.messageHandler = new MessageHandler();
|
||||
|
||||
switch(INSTANCE.vpnConfig.getDatabaseType().toLowerCase()) {
|
||||
case "h2":
|
||||
case "local":
|
||||
case "flatfile": {
|
||||
AntiVPN.getInstance().getExecutor().log("Using databaseType H2...");
|
||||
INSTANCE.database = new H2VPN();
|
||||
INSTANCE.database.init();
|
||||
break;
|
||||
}
|
||||
case "mysql":
|
||||
case "sql":{
|
||||
AntiVPN.getInstance().getExecutor().log("Using databaseType MySQL...");
|
||||
INSTANCE.database = new MySqlVPN();
|
||||
INSTANCE.database.init();
|
||||
break;
|
||||
}
|
||||
case "mongo":
|
||||
case "mongodb":
|
||||
case "mongod": {
|
||||
INSTANCE.database = new MongoVPN();
|
||||
INSTANCE.database.init();
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
AntiVPN.getInstance().getExecutor().log("Could not find database type \"" + INSTANCE.vpnConfig.getDatabaseType() + "\". " +
|
||||
"Options: [MySQL]");
|
||||
break;
|
||||
}
|
||||
}
|
||||
INSTANCE.database = new LiteDatabase();
|
||||
INSTANCE.database.init();
|
||||
|
||||
//Registering commands
|
||||
INSTANCE.registerCommands();
|
||||
@@ -109,7 +80,8 @@ public class AntiVPN {
|
||||
//of unnecessary database queries.
|
||||
if(player.hasPermission("antivpn.command.alerts")) {
|
||||
//Running database check for enabled alerts.
|
||||
INSTANCE.database.alertsState(player.getUuid(), player::setAlertsEnabled);
|
||||
INSTANCE.database.updateAlertsState(player.getUuid(), true);
|
||||
player.setAlertsEnabled(true);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -146,35 +118,7 @@ public class AntiVPN {
|
||||
public void reloadDatabase() {
|
||||
database.shutdown();
|
||||
|
||||
switch(AntiVPN.getInstance().getVpnConfig().getDatabaseType().toLowerCase()) {
|
||||
case "h2":
|
||||
case "local":
|
||||
case "flatfile": {
|
||||
AntiVPN.getInstance().getExecutor().log("Using databaseType H2...");
|
||||
INSTANCE.database = new H2VPN();
|
||||
INSTANCE.database.init();
|
||||
break;
|
||||
}
|
||||
case "mysql":
|
||||
case "sql":{
|
||||
AntiVPN.getInstance().getExecutor().log("Using databaseType MySQL...");
|
||||
INSTANCE.database = new MySqlVPN();
|
||||
INSTANCE.database.init();
|
||||
break;
|
||||
}
|
||||
case "mongo":
|
||||
case "mongodb":
|
||||
case "mongod": {
|
||||
INSTANCE.database = new MongoVPN();
|
||||
INSTANCE.database.init();
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
AntiVPN.getInstance().getExecutor().log("Could not find database type \"" + INSTANCE.vpnConfig.getDatabaseType() + "\". " +
|
||||
"Options: [MySQL]");
|
||||
break;
|
||||
}
|
||||
}
|
||||
INSTANCE.database = new LiteDatabase();
|
||||
}
|
||||
|
||||
public static AntiVPN getInstance() {
|
||||
|
||||
@@ -18,10 +18,13 @@ import java.util.function.Consumer;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public abstract class VPNExecutor {
|
||||
public static ScheduledExecutorService threadExecutor = Executors.newScheduledThreadPool(2);
|
||||
|
||||
@Getter
|
||||
private final ScheduledExecutorService threadExecutor = Executors.newScheduledThreadPool(2);
|
||||
|
||||
@Getter
|
||||
private final Set<UUID> whitelisted = Collections.synchronizedSet(new HashSet<>());
|
||||
|
||||
@Getter
|
||||
private final Set<String> whitelistedIps = Collections.synchronizedSet(new HashSet<>());
|
||||
|
||||
@@ -32,7 +35,9 @@ public abstract class VPNExecutor {
|
||||
|
||||
public abstract void registerListeners();
|
||||
|
||||
public abstract void shutdown();
|
||||
public void shutdown() {
|
||||
threadExecutor.shutdown();
|
||||
}
|
||||
|
||||
public abstract void log(Level level, String log, Object... objects);
|
||||
|
||||
|
||||
@@ -68,13 +68,13 @@ public class AllowlistCommand extends Command {
|
||||
case "add":
|
||||
case "insert": {
|
||||
AntiVPN.getInstance().getExecutor().getWhitelistedIps().add(args[1]);
|
||||
AntiVPN.getInstance().getDatabase().setWhitelisted(args[1], true);
|
||||
AntiVPN.getInstance().getDatabase().removeWhitelist(args[1]);
|
||||
return String.format("&aAdded &6%s &ato the exemption allowlist.", args[1]);
|
||||
}
|
||||
case "remove":
|
||||
case "delete": {
|
||||
AntiVPN.getInstance().getExecutor().getWhitelistedIps().remove(args[1]);
|
||||
AntiVPN.getInstance().getDatabase().setWhitelisted(args[1], false);
|
||||
AntiVPN.getInstance().getDatabase().removeWhitelist(args[1]);
|
||||
return String.format("&cRemoved &6%s &cfrom the exemption allowlist.", args[1]);
|
||||
}
|
||||
default: {
|
||||
@@ -85,12 +85,12 @@ public class AllowlistCommand extends Command {
|
||||
switch(args[0].toLowerCase()) {
|
||||
case "add":
|
||||
case "insert": {
|
||||
AntiVPN.getInstance().getDatabase().setWhitelisted(args[1], true);
|
||||
AntiVPN.getInstance().getDatabase().addWhitelist(args[1]);
|
||||
return String.format("&aAdded &6%s &a to the exemption allowlist.", args[1]);
|
||||
}
|
||||
case "remove":
|
||||
case "delete": {
|
||||
AntiVPN.getInstance().getDatabase().setWhitelisted(args[1], false);
|
||||
AntiVPN.getInstance().getDatabase().removeWhitelist(args[1]);
|
||||
return String.format("&cRemoved &6%s &c from the exemption allowlist.", args[1]);
|
||||
}
|
||||
default: {
|
||||
@@ -130,12 +130,12 @@ public class AllowlistCommand extends Command {
|
||||
} else {
|
||||
switch(args[0].toLowerCase()) {
|
||||
case "add": {
|
||||
AntiVPN.getInstance().getDatabase().setWhitelisted(uuid, true);
|
||||
AntiVPN.getInstance().getDatabase().addWhitelist(uuid);
|
||||
return String.format("&aAdded &6%s &auuid to the exemption allowlist.", uuid.toString());
|
||||
}
|
||||
case "remove":
|
||||
case "delete": {
|
||||
AntiVPN.getInstance().getDatabase().setWhitelisted(uuid, false);
|
||||
AntiVPN.getInstance().getDatabase().removeWhitelist(uuid);
|
||||
return String.format("&cRemoved &6%s &cuuid from the exemption allowlist.", uuid.toString());
|
||||
}
|
||||
default: {
|
||||
|
||||
@@ -2,10 +2,8 @@ package dev.brighten.antivpn.database;
|
||||
|
||||
import dev.brighten.antivpn.web.objects.VPNResponse;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public interface VPNDatabase {
|
||||
Optional<VPNResponse> getStoredResponse(String ip);
|
||||
@@ -14,30 +12,24 @@ public interface VPNDatabase {
|
||||
|
||||
void deleteResponse(String ip);
|
||||
|
||||
void clearResponses();
|
||||
|
||||
boolean isWhitelisted(UUID uuid);
|
||||
|
||||
boolean isWhitelisted(String ip);
|
||||
|
||||
void setWhitelisted(UUID uuid, boolean whitelisted);
|
||||
void addWhitelist(UUID uuid);
|
||||
|
||||
void setWhitelisted(String ip, boolean whitelisted);
|
||||
void addWhitelist(String cidr);
|
||||
|
||||
List<UUID> getAllWhitelisted();
|
||||
void removeWhitelist(UUID uuid);
|
||||
|
||||
List<String> getAllWhitelistedIps();
|
||||
void removeWhitelist(String cidr);
|
||||
|
||||
void getStoredResponseAsync(String ip, Consumer<Optional<VPNResponse>> result);
|
||||
|
||||
void isWhitelistedAsync(UUID uuid, Consumer<Boolean> result);
|
||||
|
||||
void isWhitelistedAsync(String ip, Consumer<Boolean> result);
|
||||
|
||||
void alertsState(UUID uuid, Consumer<Boolean> result);
|
||||
boolean getAlertsState(UUID uuid);
|
||||
|
||||
void updateAlertsState(UUID uuid, boolean state);
|
||||
|
||||
void clearResponses();
|
||||
|
||||
void init();
|
||||
|
||||
void shutdown();
|
||||
|
||||
@@ -1,276 +0,0 @@
|
||||
package dev.brighten.antivpn.database.local;
|
||||
|
||||
import dev.brighten.antivpn.AntiVPN;
|
||||
import dev.brighten.antivpn.api.VPNExecutor;
|
||||
import dev.brighten.antivpn.database.VPNDatabase;
|
||||
import dev.brighten.antivpn.database.sql.utils.MySQL;
|
||||
import dev.brighten.antivpn.database.sql.utils.Query;
|
||||
import dev.brighten.antivpn.web.objects.VPNResponse;
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class H2VPN implements VPNDatabase {
|
||||
|
||||
public H2VPN() {
|
||||
VPNExecutor.threadExecutor.scheduleAtFixedRate(() -> {
|
||||
if(!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled() || MySQL.isClosed()) return;
|
||||
|
||||
//Refreshing whitelisted players
|
||||
AntiVPN.getInstance().getExecutor().getWhitelisted().clear();
|
||||
AntiVPN.getInstance().getExecutor().getWhitelisted()
|
||||
.addAll(AntiVPN.getInstance().getDatabase().getAllWhitelisted());
|
||||
|
||||
//Refreshing whitlisted IPs
|
||||
AntiVPN.getInstance().getExecutor().getWhitelistedIps().clear();
|
||||
AntiVPN.getInstance().getExecutor().getWhitelistedIps()
|
||||
.addAll(AntiVPN.getInstance().getDatabase().getAllWhitelistedIps());
|
||||
}, 2, 30, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<VPNResponse> getStoredResponse(String ip) {
|
||||
if (!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled()|| MySQL.isClosed())
|
||||
return Optional.empty();
|
||||
|
||||
ResultSet rs = Query.prepare("select * from `responses` where `ip` = ? limit 1").append(ip).executeQuery();
|
||||
|
||||
try {
|
||||
if (rs != null && rs.next()) {
|
||||
VPNResponse response = new VPNResponse(rs.getString("asn"), rs.getString("ip"),
|
||||
rs.getString("countryName"), rs.getString("countryCode"),
|
||||
rs.getString("city"), rs.getString("timeZone"),
|
||||
rs.getString("method"), rs.getString("isp"), "N/A",
|
||||
rs.getBoolean("proxy"), rs.getBoolean("cached"), true,
|
||||
rs.getDouble("latitude"), rs.getDouble("longitude"),
|
||||
rs.getTimestamp("inserted").getTime(), -1);
|
||||
|
||||
if(System.currentTimeMillis() - response.getLastAccess() > TimeUnit.HOURS.toMillis(1)) {
|
||||
VPNExecutor.threadExecutor.execute(() -> deleteResponse(ip));
|
||||
return Optional.empty();
|
||||
}
|
||||
return Optional.of(response);
|
||||
}
|
||||
} catch (SQLException throwables) {
|
||||
throwables.printStackTrace();
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
/*
|
||||
* Query.
|
||||
* prepare("create table if not exists `responses` (`ip` varchar(45) not null, "
|
||||
* +
|
||||
* "`countryName` varchar(64), `countryCode` varchar(10), `city` varchar(64), `timeZone` varchar(64), "
|
||||
* +
|
||||
* "`method` varchar(32), `isp` varchar(32), `proxy` boolean, `cached` boolean "
|
||||
* + "`latitude` double, `longitude` double)");
|
||||
*/
|
||||
@Override
|
||||
public void cacheResponse(VPNResponse toCache) {
|
||||
if (!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled() || MySQL.isClosed())
|
||||
return;
|
||||
|
||||
Query.prepare("insert into `responses` (`ip`,`asn`,`countryName`,`countryCode`,`city`,`timeZone`,"
|
||||
+ "`method`,`isp`,`proxy`,`cached`,`inserted`,`latitude`,`longitude`) values (?,?,?,?,?,?,?,?,?,?,?,?,?)")
|
||||
.append(toCache.getIp()).append(toCache.getAsn()).append(toCache.getCountryName())
|
||||
.append(toCache.getCountryCode()).append(toCache.getCity()).append(toCache.getTimeZone())
|
||||
.append(toCache.getMethod()).append(toCache.getIsp()).append(toCache.isProxy())
|
||||
.append(toCache.isCached()).append(new Timestamp(System.currentTimeMillis()))
|
||||
.append(toCache.getLatitude()).append(toCache.getLongitude()).execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteResponse(String ip) {
|
||||
if(!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled() || MySQL.isClosed())
|
||||
return;
|
||||
|
||||
Query.prepare("delete from `responses` where `ip` = ?").append(ip).execute();
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public boolean isWhitelisted(UUID uuid) {
|
||||
if (!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled() || MySQL.isClosed())
|
||||
return false;
|
||||
ResultSet set = Query.prepare("select uuid from `whitelisted` where `uuid` = ? limit 1")
|
||||
.append(uuid.toString()).executeQuery();
|
||||
|
||||
return set != null && set.next() && set.getString("uuid") != null;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public boolean isWhitelisted(String ip) {
|
||||
if (!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled() || MySQL.isClosed())
|
||||
return false;
|
||||
ResultSet set = Query.prepare("select `ip` from `whitelisted-ips` where `ip` = ? limit 1")
|
||||
.append(ip).executeQuery();
|
||||
|
||||
|
||||
return set != null && set.next() && set.getString("ip") != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWhitelisted(UUID uuid, boolean whitelisted) {
|
||||
if (!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled() || MySQL.isClosed())
|
||||
return;
|
||||
|
||||
if (whitelisted) {
|
||||
if (!isWhitelisted(uuid)) {
|
||||
Query.prepare("insert into `whitelisted` (`uuid`) values (?)").append(uuid.toString()).execute();
|
||||
}
|
||||
AntiVPN.getInstance().getExecutor().getWhitelisted().add(uuid);
|
||||
} else {
|
||||
Query.prepare("delete from `whitelisted` where `uuid` = ?").append(uuid.toString()).execute();
|
||||
AntiVPN.getInstance().getExecutor().getWhitelisted().remove(uuid);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWhitelisted(String ip, boolean whitelisted) {
|
||||
if (!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled() || MySQL.isClosed())
|
||||
return;
|
||||
|
||||
if(whitelisted) {
|
||||
if(!isWhitelisted(ip)) {
|
||||
Query.prepare("insert into `whitelisted-ips` (`ip`) values (?)").append(ip).execute();
|
||||
}
|
||||
AntiVPN.getInstance().getExecutor().getWhitelistedIps().add(ip);
|
||||
} else {
|
||||
Query.prepare("delete from `whitelisted-ips` where `ip` = ?").append(ip).execute();
|
||||
AntiVPN.getInstance().getExecutor().getWhitelistedIps().remove(ip);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UUID> getAllWhitelisted() {
|
||||
List<UUID> uuids = new ArrayList<>();
|
||||
|
||||
if(!MySQL.isClosed()) Query.prepare("select uuid from `whitelisted`")
|
||||
.execute(set -> uuids.add(UUID.fromString(set.getString("uuid"))));
|
||||
|
||||
return uuids;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getAllWhitelistedIps() {
|
||||
List<String> ips = new ArrayList<>();
|
||||
|
||||
if(!MySQL.isClosed()) Query.prepare("select `ip` from `whitelisted-ips`")
|
||||
.execute(set -> ips.add(set.getString("ip")));
|
||||
|
||||
return ips;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getStoredResponseAsync(String ip, Consumer<Optional<VPNResponse>> result) {
|
||||
if(MySQL.isClosed()) return;
|
||||
|
||||
VPNExecutor.threadExecutor.execute(() -> result.accept(getStoredResponse(ip)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void isWhitelistedAsync(UUID uuid, Consumer<Boolean> result) {
|
||||
if(MySQL.isClosed()) return;
|
||||
|
||||
VPNExecutor.threadExecutor.execute(() -> result.accept(isWhitelisted(uuid)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void isWhitelistedAsync(String ip, Consumer<Boolean> result) {
|
||||
if(MySQL.isClosed()) return;
|
||||
|
||||
VPNExecutor.threadExecutor.execute(() -> result.accept(isWhitelisted(ip)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void alertsState(UUID uuid, Consumer<Boolean> result) {
|
||||
if(MySQL.isClosed()) return;
|
||||
|
||||
VPNExecutor.threadExecutor.execute(() -> {
|
||||
ResultSet set = Query.prepare("select * from `alerts` where `uuid` = ? limit 1")
|
||||
.append(uuid.toString()).executeQuery();
|
||||
|
||||
try {
|
||||
result.accept(set != null && set.next() && set.getString("uuid") != null);
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
result.accept(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAlertsState(UUID uuid, boolean enabled) {
|
||||
if(MySQL.isClosed()) return;
|
||||
|
||||
if(enabled) {
|
||||
//We want to make sure there isn't already a uuid inserted to prevent double insertions
|
||||
alertsState(uuid, alreadyEnabled -> { //No need to make another thread execute, already async
|
||||
if(!alreadyEnabled) {
|
||||
Query.prepare("insert into `alerts` (`uuid`) values (?)").append(uuid.toString())
|
||||
.execute();
|
||||
} //No need to insert again of already enabled
|
||||
});
|
||||
//Removing any uuid from the alerts table will disable alerts globally.
|
||||
} else VPNExecutor.threadExecutor.execute(() ->
|
||||
Query.prepare("delete from `alerts` where `uuid` = ?")
|
||||
.append(uuid.toString())
|
||||
.execute());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearResponses() {
|
||||
if(MySQL.isClosed()) return;
|
||||
|
||||
VPNExecutor.threadExecutor.execute(() -> Query.prepare("delete from `responses`").execute());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
if (!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled())
|
||||
return;
|
||||
AntiVPN.getInstance().getExecutor().log("Initializing H2...");
|
||||
MySQL.initH2();
|
||||
|
||||
AntiVPN.getInstance().getExecutor().log("Creating tables...");
|
||||
|
||||
//Running check for old table types to update
|
||||
|
||||
Query.prepare("create table if not exists `whitelisted` (`uuid` varchar(36) not null)").execute();
|
||||
Query.prepare("create table if not exists `whitelisted-ips` (`ip` varchar(45) not null)").execute();
|
||||
Query.prepare("create table if not exists `responses` (`ip` varchar(45) not null, `asn` varchar(12),"
|
||||
+ "`countryName` text, `countryCode` varchar(10), `city` text, `timeZone` varchar(64), "
|
||||
+ "`method` varchar(32), `isp` text, `proxy` boolean, `cached` boolean, `inserted` timestamp,"
|
||||
+ "`latitude` double, `longitude` double)").execute();
|
||||
Query.prepare("create table if not exists `alerts` (`uuid` varchar(36) not null)").execute();
|
||||
|
||||
AntiVPN.getInstance().getExecutor().log("Creating indexes...");
|
||||
try {
|
||||
Query.prepare("create index if not exists `uuid_1` on `whitelisted` (`uuid`)").execute();
|
||||
Query.prepare("create index if not exists `ip_1` on `responses` (`ip`)").execute();
|
||||
Query.prepare("create index if not exists `proxy_1` on `responses` (`proxy`)").execute();
|
||||
Query.prepare("create index if not exists `inserted_1` on `responses` (`inserted`)").execute();
|
||||
Query.prepare("create index if not exists `ip_1` on `whitelisted-ips` (`ip`)").execute();
|
||||
} catch (Exception e) {
|
||||
System.err.println("MySQL Excepton created" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() {
|
||||
if (!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled())
|
||||
return;
|
||||
MySQL.shutdown();
|
||||
}
|
||||
}
|
||||
@@ -1,246 +0,0 @@
|
||||
package dev.brighten.antivpn.database.mongo;
|
||||
|
||||
import com.mongodb.*;
|
||||
import com.mongodb.client.MongoClient;
|
||||
import com.mongodb.client.MongoClients;
|
||||
import com.mongodb.client.MongoCollection;
|
||||
import com.mongodb.client.MongoDatabase;
|
||||
import com.mongodb.client.model.Filters;
|
||||
import com.mongodb.client.model.Indexes;
|
||||
import com.mongodb.client.model.UpdateOptions;
|
||||
import dev.brighten.antivpn.AntiVPN;
|
||||
import dev.brighten.antivpn.api.VPNExecutor;
|
||||
import dev.brighten.antivpn.database.VPNDatabase;
|
||||
import dev.brighten.antivpn.web.objects.VPNResponse;
|
||||
import org.bson.Document;
|
||||
import org.bson.conversions.Bson;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class MongoVPN implements VPNDatabase {
|
||||
|
||||
private MongoCollection<Document> settingsDocument, cacheDocument;
|
||||
private MongoClient client;
|
||||
|
||||
public MongoVPN() {
|
||||
VPNExecutor.threadExecutor.scheduleAtFixedRate(() -> {
|
||||
if(!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled()) return;
|
||||
|
||||
//Refreshing whitelisted players
|
||||
AntiVPN.getInstance().getExecutor().getWhitelisted().clear();
|
||||
AntiVPN.getInstance().getExecutor().getWhitelisted()
|
||||
.addAll(AntiVPN.getInstance().getDatabase().getAllWhitelisted());
|
||||
|
||||
//Refreshing whitlisted IPs
|
||||
AntiVPN.getInstance().getExecutor().getWhitelistedIps().clear();
|
||||
AntiVPN.getInstance().getExecutor().getWhitelistedIps()
|
||||
.addAll(AntiVPN.getInstance().getDatabase().getAllWhitelistedIps());
|
||||
}, 2, 30, TimeUnit.SECONDS);
|
||||
}
|
||||
@Override
|
||||
public Optional<VPNResponse> getStoredResponse(String ip) {
|
||||
Document rdoc = cacheDocument.find(Filters.eq("ip", ip)).first();
|
||||
|
||||
if(rdoc != null) {
|
||||
long lastUpdate = rdoc.get("lastAccess", 0L);
|
||||
|
||||
if(System.currentTimeMillis() - lastUpdate > TimeUnit.HOURS.toMillis(1)) {
|
||||
VPNExecutor.threadExecutor.execute(() -> deleteResponse(ip));
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
return Optional.of(VPNResponse.builder().asn(rdoc.getString("asn")).ip(ip)
|
||||
.countryName(rdoc.getString("countryName"))
|
||||
.countryCode(rdoc.getString("countryCode"))
|
||||
.city(rdoc.getString("city"))
|
||||
.isp(rdoc.getString("isp"))
|
||||
.method(rdoc.getString("method"))
|
||||
.timeZone(rdoc.getString("timeZone"))
|
||||
.proxy(rdoc.getBoolean("proxy"))
|
||||
.cached(rdoc.getBoolean("cached"))
|
||||
.success(true)
|
||||
.latitude(rdoc.getDouble("latitude"))
|
||||
.longitude(rdoc.getDouble("longitude"))
|
||||
.lastAccess(rdoc.get("lastAccess", 0L))
|
||||
.build());
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cacheResponse(VPNResponse toCache) {
|
||||
Document rdoc = new Document("ip", toCache.getIp());
|
||||
|
||||
rdoc.put("asn", toCache.getAsn());
|
||||
rdoc.put("countryName", toCache.getCountryName());
|
||||
rdoc.put("countryCode", toCache.getCountryCode());
|
||||
rdoc.put("city", toCache.getCity());
|
||||
rdoc.put("isp", toCache.getIsp());
|
||||
rdoc.put("method", toCache.getMethod());
|
||||
rdoc.put("timeZone", toCache.getTimeZone());
|
||||
rdoc.put("proxy", toCache.isProxy());
|
||||
rdoc.put("cached", toCache.isCached());
|
||||
rdoc.put("success", toCache.isSuccess());
|
||||
rdoc.put("latitude", toCache.getLatitude());
|
||||
rdoc.put("longitude", toCache.getLongitude());
|
||||
rdoc.put("lastAccess", System.currentTimeMillis());
|
||||
|
||||
VPNExecutor.threadExecutor.execute(() -> {
|
||||
Bson update = new Document("$set", rdoc);
|
||||
cacheDocument.updateOne(Filters.eq("ip", toCache.getIp()), update,
|
||||
new UpdateOptions().upsert(true));
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteResponse(String ip) {
|
||||
cacheDocument.deleteMany(Filters.eq("ip", ip));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWhitelisted(UUID uuid) {
|
||||
return settingsDocument
|
||||
.find(Filters.and(Filters.eq("setting", "whitelist"),
|
||||
Filters.eq("uuid", uuid.toString()))).first() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWhitelisted(String ip) {
|
||||
return settingsDocument
|
||||
.find(Filters.and(Filters.eq("setting", "whitelist"),
|
||||
Filters.eq("ip", ip))).first() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWhitelisted(UUID uuid, boolean whitelisted) {
|
||||
if(whitelisted) {
|
||||
Document wdoc = new Document("setting", "whitelist");
|
||||
wdoc.put("uuid", uuid.toString());
|
||||
AntiVPN.getInstance().getExecutor().getWhitelisted().add(uuid);
|
||||
VPNExecutor.threadExecutor.execute(() -> settingsDocument.insertOne(wdoc));
|
||||
} else {
|
||||
AntiVPN.getInstance().getExecutor().getWhitelisted().remove(uuid);
|
||||
VPNExecutor.threadExecutor.execute(() -> settingsDocument.deleteMany(Filters
|
||||
.and(
|
||||
Filters.eq("setting", "whitelist"),
|
||||
Filters.eq("uuid", uuid.toString()))));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWhitelisted(String ip, boolean whitelisted) {
|
||||
if(whitelisted) {
|
||||
Document wdoc = new Document("setting", "whitelist").append("ip", ip);
|
||||
|
||||
AntiVPN.getInstance().getExecutor().getWhitelistedIps().add(ip);
|
||||
VPNExecutor.threadExecutor.execute(() -> settingsDocument.insertOne(wdoc));
|
||||
} else {
|
||||
AntiVPN.getInstance().getExecutor().getWhitelistedIps().remove(ip);
|
||||
VPNExecutor.threadExecutor.execute(() -> settingsDocument.deleteMany(Filters
|
||||
.and(
|
||||
Filters.eq("setting", "whitelist"),
|
||||
Filters.eq("ip", ip))));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UUID> getAllWhitelisted() {
|
||||
List<UUID> uuids = new ArrayList<>();
|
||||
settingsDocument.find(Filters.and(Filters.eq("setting", "whitelist"),
|
||||
Filters.exists("uuid")))
|
||||
.forEach((Consumer<? super Document>) doc -> uuids.add(UUID.fromString(doc.getString("uuid"))));
|
||||
return uuids;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getAllWhitelistedIps() {
|
||||
List<String> ips = new ArrayList<>();
|
||||
settingsDocument.find(Filters.and(Filters.eq("setting", "whitelist"),
|
||||
Filters.exists("ip")))
|
||||
.forEach((Consumer<? super Document>) doc -> ips.add(doc.getString("ip")));
|
||||
return ips;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getStoredResponseAsync(String ip, Consumer<Optional<VPNResponse>> result) {
|
||||
VPNExecutor.threadExecutor.execute(() -> result.accept(getStoredResponse(ip)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void isWhitelistedAsync(UUID uuid, Consumer<Boolean> result) {
|
||||
VPNExecutor.threadExecutor.execute(() -> result.accept(isWhitelisted(uuid)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void isWhitelistedAsync(String ip, Consumer<Boolean> result) {
|
||||
VPNExecutor.threadExecutor.execute(() -> result.accept(isWhitelisted(ip)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void alertsState(UUID uuid, Consumer<Boolean> result) {
|
||||
VPNExecutor.threadExecutor.execute(() -> result.accept(settingsDocument
|
||||
.find(Filters.and(Filters.eq("setting", "alerts"),
|
||||
Filters.eq("uuid", uuid.toString()))).first() != null));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAlertsState(UUID uuid, boolean state) {
|
||||
VPNExecutor.threadExecutor.execute(() -> {
|
||||
settingsDocument.deleteMany(Filters.and(Filters.eq("setting", "alerts"),
|
||||
Filters.eq("uuid", uuid.toString())));
|
||||
if(state) {
|
||||
Document adoc = new Document("setting", "alerts");
|
||||
|
||||
adoc.put("uuid", uuid.toString());
|
||||
settingsDocument.insertOne(adoc);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearResponses() {
|
||||
cacheDocument.deleteMany(Filters.exists("ip"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
if(!AntiVPN.getInstance().getVpnConfig().mongoDatabaseURL().isEmpty()) { //URL
|
||||
ConnectionString cs = new ConnectionString(AntiVPN.getInstance().getVpnConfig().mongoDatabaseURL());
|
||||
MongoClientSettings settings = MongoClientSettings.builder().applyConnectionString(cs).build();
|
||||
client = MongoClients.create(settings);
|
||||
} else {
|
||||
MongoClientSettings.Builder settingsBld = MongoClientSettings.builder().readPreference(ReadPreference.nearest())
|
||||
.applyToClusterSettings(builder -> builder.
|
||||
hosts(Collections.singletonList(
|
||||
new ServerAddress(
|
||||
AntiVPN.getInstance().getVpnConfig().getIp(),
|
||||
AntiVPN.getInstance().getVpnConfig().getPort())
|
||||
)));
|
||||
if(AntiVPN.getInstance().getVpnConfig().useDatabaseCreds()) {
|
||||
settingsBld.credential(MongoCredential
|
||||
.createCredential(AntiVPN.getInstance().getVpnConfig().getUsername(),
|
||||
AntiVPN.getInstance().getVpnConfig().getDatabaseName(),
|
||||
AntiVPN.getInstance().getVpnConfig().getPassword().toCharArray()));
|
||||
}
|
||||
|
||||
client = MongoClients.create(settingsBld.build());
|
||||
}
|
||||
MongoDatabase antivpnDatabase = client.getDatabase(AntiVPN.getInstance().getVpnConfig().getDatabaseName());
|
||||
|
||||
settingsDocument = antivpnDatabase.getCollection("settings");
|
||||
if(settingsDocument.listIndexes().first() == null) {
|
||||
AntiVPN.getInstance().getExecutor().log("Created index for settings collection!");
|
||||
settingsDocument.createIndex(Indexes.ascending("ip"));
|
||||
}
|
||||
cacheDocument = antivpnDatabase.getCollection("cache");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() {
|
||||
settingsDocument = null;
|
||||
cacheDocument = null;
|
||||
client.close();
|
||||
}
|
||||
}
|
||||
@@ -1,347 +0,0 @@
|
||||
package dev.brighten.antivpn.database.sql;
|
||||
|
||||
import dev.brighten.antivpn.AntiVPN;
|
||||
import dev.brighten.antivpn.api.VPNExecutor;
|
||||
import dev.brighten.antivpn.database.VPNDatabase;
|
||||
import dev.brighten.antivpn.database.sql.utils.MySQL;
|
||||
import dev.brighten.antivpn.database.sql.utils.Query;
|
||||
import dev.brighten.antivpn.web.objects.VPNResponse;
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class MySqlVPN implements VPNDatabase {
|
||||
|
||||
public MySqlVPN() {
|
||||
VPNExecutor.threadExecutor.scheduleAtFixedRate(() -> {
|
||||
if(!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled() || MySQL.isClosed()) return;
|
||||
|
||||
//Refreshing whitelisted players
|
||||
AntiVPN.getInstance().getExecutor().getWhitelisted().clear();
|
||||
AntiVPN.getInstance().getExecutor().getWhitelisted()
|
||||
.addAll(AntiVPN.getInstance().getDatabase().getAllWhitelisted());
|
||||
|
||||
//Refreshing whitlisted IPs
|
||||
AntiVPN.getInstance().getExecutor().getWhitelistedIps().clear();
|
||||
AntiVPN.getInstance().getExecutor().getWhitelistedIps()
|
||||
.addAll(AntiVPN.getInstance().getDatabase().getAllWhitelistedIps());
|
||||
}, 2, 30, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<VPNResponse> getStoredResponse(String ip) {
|
||||
if (isDisabled())
|
||||
return Optional.empty();
|
||||
|
||||
ResultSet rs = Query.prepare("select * from `responses` where `ip` = ? limit 1").append(ip).executeQuery();
|
||||
|
||||
try {
|
||||
if (rs != null && rs.next()) {
|
||||
VPNResponse response = new VPNResponse(rs.getString("asn"), rs.getString("ip"),
|
||||
rs.getString("countryName"), rs.getString("countryCode"),
|
||||
rs.getString("city"), rs.getString("timeZone"),
|
||||
rs.getString("method"), rs.getString("isp"), "N/A",
|
||||
rs.getBoolean("proxy"), rs.getBoolean("cached"), true,
|
||||
rs.getDouble("latitude"), rs.getDouble("longitude"),
|
||||
rs.getTimestamp("inserted").getTime(), -1);
|
||||
|
||||
if(System.currentTimeMillis() - response.getLastAccess() > TimeUnit.HOURS.toMillis(1)) {
|
||||
VPNExecutor.threadExecutor.execute(() -> deleteResponse(ip));
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
return Optional.of(response);
|
||||
}
|
||||
} catch (SQLException throwables) {
|
||||
throwables.printStackTrace();
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
/*
|
||||
* Query.
|
||||
* prepare("create table if not exists `responses` (`ip` varchar(45) not null, "
|
||||
* +
|
||||
* "`countryName` varchar(64), `countryCode` varchar(10), `city` varchar(64), `timeZone` varchar(64), "
|
||||
* +
|
||||
* "`method` varchar(32), `isp` varchar(32), `proxy` boolean, `cached` boolean "
|
||||
* + "`latitude` double, `longitude` double)");
|
||||
*/
|
||||
@Override
|
||||
public void cacheResponse(VPNResponse toCache) {
|
||||
if (isDisabled())
|
||||
return;
|
||||
|
||||
Query.prepare("insert into `responses` (`ip`,`asn`,`countryName`,`countryCode`,`city`,`timeZone`,"
|
||||
+ "`method`,`isp`,`proxy`,`cached`,`inserted`,`latitude`,`longitude`) values (?,?,?,?,?,?,?,?,?,?,?,?,?)")
|
||||
.append(toCache.getIp()).append(toCache.getAsn()).append(toCache.getCountryName())
|
||||
.append(toCache.getCountryCode()).append(toCache.getCity()).append(toCache.getTimeZone())
|
||||
.append(toCache.getMethod()).append(toCache.getIsp()).append(toCache.isProxy())
|
||||
.append(toCache.isCached()).append(new Timestamp(System.currentTimeMillis()))
|
||||
.append(toCache.getLatitude()).append(toCache.getLongitude()).execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteResponse(String ip) {
|
||||
if(!isDisabled())
|
||||
return;
|
||||
|
||||
Query.prepare("delete from `responses` where `ip` = ?").append(ip).execute();
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public boolean isWhitelisted(UUID uuid) {
|
||||
if (isDisabled())
|
||||
return false;
|
||||
ResultSet set = Query.prepare("select uuid from `whitelisted` where `uuid` = ? limit 1")
|
||||
.append(uuid.toString()).executeQuery();
|
||||
|
||||
return set != null && set.next() && set.getString("uuid") != null;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public boolean isWhitelisted(String ip) {
|
||||
if (isDisabled())
|
||||
return false;
|
||||
ResultSet set = Query.prepare("select `ip` from `whitelisted-ips` where `ip` = ? limit 1")
|
||||
.append(ip).executeQuery();
|
||||
|
||||
|
||||
return set != null && set.next() && set.getString("ip") != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWhitelisted(UUID uuid, boolean whitelisted) {
|
||||
if (isDisabled())
|
||||
return;
|
||||
|
||||
if (whitelisted) {
|
||||
if (!isWhitelisted(uuid)) {
|
||||
Query.prepare("insert into `whitelisted` (`uuid`) values (?)").append(uuid.toString()).execute();
|
||||
}
|
||||
AntiVPN.getInstance().getExecutor().getWhitelisted().add(uuid);
|
||||
} else {
|
||||
Query.prepare("delete from `whitelisted` where `uuid` = ?").append(uuid.toString()).execute();
|
||||
AntiVPN.getInstance().getExecutor().getWhitelisted().remove(uuid);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWhitelisted(String ip, boolean whitelisted) {
|
||||
if (isDisabled())
|
||||
return;
|
||||
|
||||
if(whitelisted) {
|
||||
if(!isWhitelisted(ip)) {
|
||||
Query.prepare("insert into `whitelisted-ips` (`ip`) values (?)").append(ip).execute();
|
||||
}
|
||||
AntiVPN.getInstance().getExecutor().getWhitelistedIps().add(ip);
|
||||
} else {
|
||||
Query.prepare("delete from `whitelisted-ips` where `ip` = ?").append(ip).execute();
|
||||
AntiVPN.getInstance().getExecutor().getWhitelistedIps().remove(ip);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UUID> getAllWhitelisted() {
|
||||
List<UUID> uuids = new ArrayList<>();
|
||||
|
||||
if(!MySQL.isClosed()) Query.prepare("select uuid from `whitelisted`")
|
||||
.execute(set -> uuids.add(UUID.fromString(set.getString("uuid"))));
|
||||
|
||||
return uuids;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getAllWhitelistedIps() {
|
||||
List<String> ips = new ArrayList<>();
|
||||
|
||||
if(!MySQL.isClosed()) Query.prepare("select `ip` from `whitelisted-ips`")
|
||||
.execute(set -> ips.add(set.getString("ip")));
|
||||
|
||||
return ips;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getStoredResponseAsync(String ip, Consumer<Optional<VPNResponse>> result) {
|
||||
if(MySQL.isClosed()) return;
|
||||
|
||||
VPNExecutor.threadExecutor.execute(() -> result.accept(getStoredResponse(ip)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void isWhitelistedAsync(UUID uuid, Consumer<Boolean> result) {
|
||||
if(MySQL.isClosed()) return;
|
||||
|
||||
VPNExecutor.threadExecutor.execute(() -> result.accept(isWhitelisted(uuid)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void isWhitelistedAsync(String ip, Consumer<Boolean> result) {
|
||||
if(MySQL.isClosed()) return;
|
||||
|
||||
VPNExecutor.threadExecutor.execute(() -> result.accept(isWhitelisted(ip)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void alertsState(UUID uuid, Consumer<Boolean> result) {
|
||||
if(MySQL.isClosed()) return;
|
||||
|
||||
VPNExecutor.threadExecutor.execute(() -> {
|
||||
ResultSet set = Query.prepare("select * from `alerts` where `uuid` = ? limit 1")
|
||||
.append(uuid.toString()).executeQuery();
|
||||
|
||||
try {
|
||||
result.accept(set != null && set.next() && set.getString("uuid") != null);
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
result.accept(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAlertsState(UUID uuid, boolean enabled) {
|
||||
if(MySQL.isClosed()) return;
|
||||
|
||||
if(enabled) {
|
||||
//We want to make sure there isn't already a uuid inserted to prevent double insertions
|
||||
alertsState(uuid, alreadyEnabled -> { //No need to make another thread execute, already async
|
||||
if(!alreadyEnabled) {
|
||||
Query.prepare("insert into `alerts` (`uuid`) values (?)").append(uuid.toString())
|
||||
.execute();
|
||||
} //No need to insert again of already enabled
|
||||
});
|
||||
//Removing any uuid from the alerts table will disable alerts globally.
|
||||
} else VPNExecutor.threadExecutor.execute(() ->
|
||||
Query.prepare("delete from `alerts` where `uuid` = ?")
|
||||
.append(uuid.toString())
|
||||
.execute());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearResponses() {
|
||||
if(MySQL.isClosed()) return;
|
||||
|
||||
VPNExecutor.threadExecutor.execute(() -> Query.prepare("delete from `responses`").execute());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
if (!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled())
|
||||
return;
|
||||
AntiVPN.getInstance().getExecutor().log("Initializing MySQL...");
|
||||
MySQL.init();
|
||||
|
||||
AntiVPN.getInstance().getExecutor().log("Creating tables...");
|
||||
|
||||
//Running check for old table types to update
|
||||
oldTableCheck: {
|
||||
Query.prepare("select `DATA_TYPE` from INFORMATION_SCHEMA.COLUMNS " +
|
||||
"WHERE table_name = 'responses' AND COLUMN_NAME = 'isp';").execute(set -> {
|
||||
if(set.getObject("DATA_TYPE").toString().contains("varchar")) {
|
||||
AntiVPN.getInstance().getExecutor().log("Using old database format for storing responses! " +
|
||||
"Dropping table and creating a new one...");
|
||||
if(Query.prepare("drop table `responses`").execute() > 0) {
|
||||
AntiVPN.getInstance().getExecutor().log("Successfully dropped table!");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Query.prepare("create table if not exists `whitelisted` (`uuid` varchar(36) not null)").execute();
|
||||
Query.prepare("create table if not exists `whitelisted-ips` (`ip` varchar(45) not null)").execute();
|
||||
Query.prepare("create table if not exists `responses` (`ip` varchar(45) not null, `asn` varchar(12),"
|
||||
+ "`countryName` text, `countryCode` varchar(10), `city` text, `timeZone` varchar(64), "
|
||||
+ "`method` varchar(32), `isp` text, `proxy` boolean, `cached` boolean, `inserted` timestamp,"
|
||||
+ "`latitude` double, `longitude` double)").execute();
|
||||
Query.prepare("create table if not exists `alerts` (`uuid` varchar(36) not null)").execute();
|
||||
|
||||
AntiVPN.getInstance().getExecutor().log("Creating indexes...");
|
||||
try {
|
||||
// Ref:
|
||||
// https://dba.stackexchange.com/questions/24531/mysql-create-index-if-not-exists
|
||||
|
||||
String query = "SELECT COUNT(1) IndexExists FROM INFORMATION_SCHEMA.STATISTICS WHERE table_schema=DATABASE()" +
|
||||
" AND table_name='whitelisted' AND index_name='uuid_1';";
|
||||
ResultSet rs = Query.prepare(query).executeQuery();
|
||||
int id = 0;
|
||||
whitelistedIndex: {
|
||||
while (rs.next()) {
|
||||
id = rs.getInt("IndexExists");
|
||||
}
|
||||
if (id == 0) {
|
||||
Query.prepare("create index `uuid_1` on `whitelisted` (`uuid`)").execute();
|
||||
}
|
||||
id = 0;
|
||||
}
|
||||
responsesIndex: {
|
||||
query = "SELECT COUNT(1) IndexExists FROM INFORMATION_SCHEMA.STATISTICS WHERE table_schema=DATABASE() " +
|
||||
"AND table_name='responses' AND index_name='ip_1';";
|
||||
rs = Query.prepare(query).executeQuery();
|
||||
while (rs.next()) {
|
||||
id = rs.getInt("IndexExists");
|
||||
}
|
||||
if (id == 0) {
|
||||
Query.prepare("create index `ip_1` on `responses` (`ip`)").execute();
|
||||
}
|
||||
id = 0;
|
||||
query = "SELECT COUNT(1) IndexExists FROM INFORMATION_SCHEMA.STATISTICS WHERE table_schema=DATABASE() " +
|
||||
"AND table_name='responses' AND index_name='proxy_1';";
|
||||
rs = Query.prepare(query).executeQuery();
|
||||
while (rs.next()) {
|
||||
id = rs.getInt("IndexExists");
|
||||
}
|
||||
if (id == 0) {
|
||||
Query.prepare("create index `proxy_1` on `responses` (`proxy`)").execute();
|
||||
}
|
||||
id = 0;
|
||||
query = "SELECT COUNT(1) IndexExists FROM INFORMATION_SCHEMA.STATISTICS WHERE table_schema=DATABASE()" +
|
||||
" AND table_name='responses' AND index_name='inserted_1';";
|
||||
rs = Query.prepare(query).executeQuery();
|
||||
while (rs.next()) {
|
||||
id = rs.getInt("IndexExists");
|
||||
}
|
||||
if (id == 0) {
|
||||
Query.prepare("create index `inserted_1` on `responses` (`inserted`)").execute();
|
||||
}
|
||||
id = 0;
|
||||
}
|
||||
whitelistedIpsIndex: {
|
||||
query = "SELECT COUNT(1) IndexExists FROM INFORMATION_SCHEMA.STATISTICS WHERE table_schema=DATABASE()" +
|
||||
" AND table_name='whitelisted-ips' AND index_name='ip_1';";
|
||||
rs = Query.prepare(query).executeQuery();
|
||||
while (rs.next()) {
|
||||
id = rs.getInt("IndexExists");
|
||||
}
|
||||
if (id == 0) {
|
||||
Query.prepare("create index `ip_1` on `whitelisted-ips` (`ip`)").execute();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.err.println("MySQL Excepton created" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isDisabled() {
|
||||
return !AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled()|| MySQL.isClosed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() {
|
||||
if (!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled())
|
||||
return;
|
||||
MySQL.shutdown();
|
||||
}
|
||||
}
|
||||
-138
@@ -1,138 +0,0 @@
|
||||
package dev.brighten.antivpn.database.sql.utils;
|
||||
|
||||
import dev.brighten.antivpn.utils.MiscUtils;
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ExecutableStatement {
|
||||
private PreparedStatement statement;
|
||||
private int pos = 1;
|
||||
|
||||
public ExecutableStatement(PreparedStatement statement) {
|
||||
this.statement = statement;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public Integer execute() {
|
||||
try {
|
||||
return statement.executeUpdate();
|
||||
} finally {
|
||||
MiscUtils.close(statement);
|
||||
}
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public void execute(ResultSetIterator iterator) {
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
rs = statement.executeQuery();
|
||||
while (rs.next()) iterator.next(rs);
|
||||
} finally {
|
||||
MiscUtils.close(statement, rs);
|
||||
}
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public void executeSingle(ResultSetIterator iterator) {
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
rs = statement.executeQuery();
|
||||
if (rs.next()) iterator.next(rs);
|
||||
else iterator.next(null);
|
||||
} finally {
|
||||
MiscUtils.close(statement, rs);
|
||||
}
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public ResultSet executeQuery() {
|
||||
return statement.executeQuery();
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public ExecutableStatement append(Object obj) {
|
||||
statement.setObject(pos++, obj);
|
||||
return this;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public ExecutableStatement append(String obj) {
|
||||
statement.setString(pos++, obj);
|
||||
return this;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public ExecutableStatement append(UUID uuid) {
|
||||
if (uuid != null) statement.setString(pos++, uuid.toString().replace("-", ""));
|
||||
else statement.setString(pos++, null);
|
||||
return this;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public ExecutableStatement append(Array obj) {
|
||||
statement.setArray(pos++, obj);
|
||||
return this;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public ExecutableStatement append(Integer obj) {
|
||||
statement.setInt(pos++, obj);
|
||||
return this;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public ExecutableStatement append(Short obj) {
|
||||
statement.setShort(pos++, obj);
|
||||
return this;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public ExecutableStatement append(Long obj) {
|
||||
statement.setLong(pos++, obj);
|
||||
return this;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public ExecutableStatement append(Float obj) {
|
||||
statement.setFloat(pos++, obj);
|
||||
return this;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public ExecutableStatement append(Double obj) {
|
||||
statement.setDouble(pos++, obj);
|
||||
return this;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public ExecutableStatement append(Date obj) {
|
||||
statement.setDate(pos++, obj);
|
||||
return this;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public ExecutableStatement append(Timestamp obj) {
|
||||
statement.setTimestamp(pos++, obj);
|
||||
return this;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public ExecutableStatement append(Time obj) {
|
||||
statement.setTime(pos++, obj);
|
||||
return this;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public ExecutableStatement append(Blob obj) {
|
||||
statement.setBlob(pos++, obj);
|
||||
return this;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public ExecutableStatement append(byte[] obj) {
|
||||
statement.setBytes(pos++, obj);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
package dev.brighten.antivpn.database.sql.utils;
|
||||
|
||||
import com.mysql.cj.jdbc.Driver;
|
||||
import dev.brighten.antivpn.AntiVPN;
|
||||
import org.h2.jdbc.JdbcConnection;
|
||||
|
||||
import java.io.File;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Properties;
|
||||
|
||||
public class MySQL {
|
||||
private static Connection conn;
|
||||
|
||||
public static void init() {
|
||||
try {
|
||||
if (conn == null || conn.isClosed()) {
|
||||
DriverManager.registerDriver(new Driver());
|
||||
conn = DriverManager.getConnection("jdbc:mysql://" + AntiVPN.getInstance().getVpnConfig().getIp()
|
||||
+ ":" + AntiVPN.getInstance().getVpnConfig().getPort()
|
||||
+ "/?useSSL=true&autoReconnect=true",
|
||||
AntiVPN.getInstance().getVpnConfig().getUsername(),
|
||||
AntiVPN.getInstance().getVpnConfig().getPassword());
|
||||
conn.setAutoCommit(true);
|
||||
Query.use(conn);
|
||||
Query.prepare("CREATE DATABASE IF NOT EXISTS `"
|
||||
+ AntiVPN.getInstance().getVpnConfig().getDatabaseName() + "`").execute();
|
||||
Query.prepare("USE `" + AntiVPN.getInstance().getVpnConfig().getDatabaseName() + "`").execute();
|
||||
AntiVPN.getInstance().getExecutor().log("Connection to MySQL has been established.");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
AntiVPN.getInstance().getExecutor().logException("Failed to load mysql: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void initH2() {
|
||||
File dataFolder = new File(AntiVPN.getInstance().getPluginFolder(), "databases");
|
||||
File databaseFile = new File(dataFolder, "database");
|
||||
try {
|
||||
conn = new NonClosableConnection(new JdbcConnection("jdbc:h2:file:" +
|
||||
databaseFile.getAbsolutePath(),
|
||||
new Properties(), AntiVPN.getInstance().getVpnConfig().getUsername(),
|
||||
AntiVPN.getInstance().getVpnConfig().getPassword(), false));
|
||||
conn.setAutoCommit(true);
|
||||
Query.use(conn);
|
||||
AntiVPN.getInstance().getExecutor().log("Connection to H2 has been established.");
|
||||
} catch (SQLException ex) {
|
||||
AntiVPN.getInstance().getExecutor().logException("H2 exception on initialize: " + ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
public static void use() {
|
||||
try {
|
||||
init();
|
||||
} catch (Exception e) {
|
||||
AntiVPN.getInstance().getExecutor().logException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void shutdown() {
|
||||
try {
|
||||
if(conn != null && !conn.isClosed()) {
|
||||
if(conn instanceof NonClosableConnection) {
|
||||
((NonClosableConnection)conn).shutdown();
|
||||
} else conn.close();
|
||||
conn = null;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
AntiVPN.getInstance().getExecutor().logException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isClosed() {
|
||||
if(conn == null)
|
||||
return true;
|
||||
|
||||
try {
|
||||
return conn.isClosed();
|
||||
} catch (SQLException e) {
|
||||
AntiVPN.getInstance().getExecutor().logException(e);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
-122
@@ -1,122 +0,0 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* Copyright (c) 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 dev.brighten.antivpn.database.sql.utils;
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
* A wrapper around a {@link Connection} which blocks usage of the default {@link #close()} method.
|
||||
*/
|
||||
public class NonClosableConnection implements Connection {
|
||||
private final Connection delegate;
|
||||
|
||||
public NonClosableConnection(Connection delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Actually {@link #close() closes} the underlying connection.
|
||||
*/
|
||||
public final void shutdown() throws SQLException {
|
||||
this.delegate.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void close() throws SQLException {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isWrapperFor(Class<?> iface) throws SQLException {
|
||||
return iface.isInstance(this.delegate) || this.delegate.isWrapperFor(iface);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public final <T> T unwrap(Class<T> iface) throws SQLException {
|
||||
if (iface.isInstance(this.delegate)) {
|
||||
return (T) this.delegate;
|
||||
}
|
||||
return this.delegate.unwrap(iface);
|
||||
}
|
||||
|
||||
// Forward to the delegate connection
|
||||
@Override public Statement createStatement() throws SQLException { return this.delegate.createStatement(); }
|
||||
@Override public PreparedStatement prepareStatement(String sql) throws SQLException { return this.delegate.prepareStatement(sql); }
|
||||
@Override public CallableStatement prepareCall(String sql) throws SQLException { return this.delegate.prepareCall(sql); }
|
||||
@Override public String nativeSQL(String sql) throws SQLException { return this.delegate.nativeSQL(sql); }
|
||||
@Override public void setAutoCommit(boolean autoCommit) throws SQLException { this.delegate.setAutoCommit(autoCommit); }
|
||||
@Override public boolean getAutoCommit() throws SQLException { return this.delegate.getAutoCommit(); }
|
||||
@Override public void commit() throws SQLException { this.delegate.commit(); }
|
||||
@Override public void rollback() throws SQLException { this.delegate.rollback(); }
|
||||
@Override public boolean isClosed() throws SQLException { return this.delegate.isClosed(); }
|
||||
@Override public DatabaseMetaData getMetaData() throws SQLException { return this.delegate.getMetaData(); }
|
||||
@Override public void setReadOnly(boolean readOnly) throws SQLException { this.delegate.setReadOnly(readOnly); }
|
||||
@Override public boolean isReadOnly() throws SQLException { return this.delegate.isReadOnly(); }
|
||||
@Override public void setCatalog(String catalog) throws SQLException { this.delegate.setCatalog(catalog); }
|
||||
@Override public String getCatalog() throws SQLException { return this.delegate.getCatalog(); }
|
||||
@Override public void setTransactionIsolation(int level) throws SQLException { this.delegate.setTransactionIsolation(level); }
|
||||
@Override public int getTransactionIsolation() throws SQLException { return this.delegate.getTransactionIsolation(); }
|
||||
@Override public SQLWarning getWarnings() throws SQLException { return this.delegate.getWarnings(); }
|
||||
@Override public void clearWarnings() throws SQLException { this.delegate.clearWarnings(); }
|
||||
@Override public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException { return this.delegate.createStatement(resultSetType, resultSetConcurrency); }
|
||||
@Override public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { return this.delegate.prepareStatement(sql, resultSetType, resultSetConcurrency); }
|
||||
@Override public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { return this.delegate.prepareCall(sql, resultSetType, resultSetConcurrency); }
|
||||
@Override public Map<String, Class<?>> getTypeMap() throws SQLException { return this.delegate.getTypeMap(); }
|
||||
@Override public void setTypeMap(Map<String, Class<?>> map) throws SQLException { this.delegate.setTypeMap(map); }
|
||||
@Override public void setHoldability(int holdability) throws SQLException { this.delegate.setHoldability(holdability); }
|
||||
@Override public int getHoldability() throws SQLException { return this.delegate.getHoldability(); }
|
||||
@Override public Savepoint setSavepoint() throws SQLException { return this.delegate.setSavepoint(); }
|
||||
@Override public Savepoint setSavepoint(String name) throws SQLException { return this.delegate.setSavepoint(name); }
|
||||
@Override public void rollback(Savepoint savepoint) throws SQLException { this.delegate.rollback(savepoint); }
|
||||
@Override public void releaseSavepoint(Savepoint savepoint) throws SQLException { this.delegate.releaseSavepoint(savepoint); }
|
||||
@Override public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { return this.delegate.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability); }
|
||||
@Override public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { return this.delegate.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability); }
|
||||
@Override public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { return this.delegate.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability); }
|
||||
@Override public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException { return this.delegate.prepareStatement(sql, autoGeneratedKeys); }
|
||||
@Override public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException { return this.delegate.prepareStatement(sql, columnIndexes); }
|
||||
@Override public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException { return this.delegate.prepareStatement(sql, columnNames); }
|
||||
@Override public Clob createClob() throws SQLException { return this.delegate.createClob(); }
|
||||
@Override public Blob createBlob() throws SQLException { return this.delegate.createBlob(); }
|
||||
@Override public NClob createNClob() throws SQLException { return this.delegate.createNClob(); }
|
||||
@Override public SQLXML createSQLXML() throws SQLException { return this.delegate.createSQLXML(); }
|
||||
@Override public boolean isValid(int timeout) throws SQLException { return this.delegate.isValid(timeout); }
|
||||
@Override public void setClientInfo(String name, String value) throws SQLClientInfoException { this.delegate.setClientInfo(name, value); }
|
||||
@Override public void setClientInfo(Properties properties) throws SQLClientInfoException { this.delegate.setClientInfo(properties); }
|
||||
@Override public String getClientInfo(String name) throws SQLException { return this.delegate.getClientInfo(name); }
|
||||
@Override public Properties getClientInfo() throws SQLException { return this.delegate.getClientInfo(); }
|
||||
@Override public Array createArrayOf(String typeName, Object[] elements) throws SQLException { return this.delegate.createArrayOf(typeName, elements); }
|
||||
@Override public Struct createStruct(String typeName, Object[] attributes) throws SQLException { return this.delegate.createStruct(typeName, attributes); }
|
||||
@Override public void setSchema(String schema) throws SQLException { this.delegate.setSchema(schema); }
|
||||
@Override public String getSchema() throws SQLException { return this.delegate.getSchema(); }
|
||||
@Override public void abort(Executor executor) throws SQLException { this.delegate.abort(executor); }
|
||||
@Override public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException { this.delegate.setNetworkTimeout(executor, milliseconds); }
|
||||
@Override public int getNetworkTimeout() throws SQLException { return this.delegate.getNetworkTimeout(); }
|
||||
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
package dev.brighten.antivpn.database.sql.utils;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
import java.sql.Connection;
|
||||
|
||||
public class Query {
|
||||
private static Connection conn;
|
||||
|
||||
public static void use(Connection conn) {
|
||||
Query.conn = conn;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static ExecutableStatement prepare(String query) {
|
||||
return new ExecutableStatement(conn.prepareStatement(query));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@SneakyThrows
|
||||
public static ExecutableStatement prepare(String query, Connection con) {
|
||||
return new ExecutableStatement(con.prepareStatement(query));
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package dev.brighten.antivpn.database.sql.utils;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
|
||||
public interface ResultSetIterator {
|
||||
void next(ResultSet rs) throws Exception;
|
||||
}
|
||||
@@ -0,0 +1,238 @@
|
||||
package dev.brighten.antivpn.database.sqllite;
|
||||
|
||||
import dev.brighten.antivpn.AntiVPN;
|
||||
import dev.brighten.antivpn.database.VPNDatabase;
|
||||
import dev.brighten.antivpn.database.sqllite.version.Version;
|
||||
import dev.brighten.antivpn.utils.CIDRUtils;
|
||||
import dev.brighten.antivpn.utils.IpUtils;
|
||||
import dev.brighten.antivpn.utils.StringUtil;
|
||||
import dev.brighten.antivpn.utils.json.JSONException;
|
||||
import dev.brighten.antivpn.web.objects.VPNResponse;
|
||||
import org.intellij.lang.annotations.Language;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.net.UnknownHostException;
|
||||
import java.sql.*;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
public class LiteDatabase implements VPNDatabase {
|
||||
|
||||
private Connection connection;
|
||||
|
||||
@Override
|
||||
public Optional<VPNResponse> getStoredResponse(String ip) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cacheResponse(VPNResponse toCache) {
|
||||
String jsonResponse;
|
||||
try {
|
||||
jsonResponse = toCache.toJson().toString();
|
||||
} catch (JSONException e) {
|
||||
AntiVPN.getInstance().getExecutor().logException(e);
|
||||
return;
|
||||
}
|
||||
|
||||
String hashedIp = StringUtil.getHash(toCache.getIp());
|
||||
|
||||
try {
|
||||
statement("INSERT INTO vpn_responses (ip, response) VALUES (?, ?)", hashedIp, jsonResponse);
|
||||
} catch (SQLException e) {
|
||||
AntiVPN.getInstance().getExecutor().logException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteResponse(String ip) {
|
||||
String hashedIp = StringUtil.getHash(ip);
|
||||
|
||||
try {
|
||||
statement("DELETE FROM vpn_responses WHERE ip = ?", hashedIp);
|
||||
} catch (SQLException e) {
|
||||
AntiVPN.getInstance().getExecutor().logException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearResponses() {
|
||||
try {
|
||||
statement("DELETE FROM vpn_responses");
|
||||
} catch (SQLException e) {
|
||||
AntiVPN.getInstance().getExecutor().logException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWhitelisted(UUID uuid) {
|
||||
try(ResultSet result = query("SELECT * FROM whitelist WHERE uuid = ?", uuid.toString())) {
|
||||
return result.next();
|
||||
} catch (SQLException e) {
|
||||
AntiVPN.getInstance().getExecutor().logException(e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWhitelisted(String ip) {
|
||||
CIDRUtils cidr;
|
||||
BigDecimal start, end;
|
||||
try {
|
||||
cidr = new CIDRUtils(ip);
|
||||
|
||||
start = IpUtils.getIpDecimal(cidr.getStartAddress().getHostAddress()).orElseThrow();
|
||||
end = IpUtils.getIpDecimal(cidr.getEndAddress().getHostAddress()).orElseThrow();
|
||||
} catch (UnknownHostException e) {
|
||||
AntiVPN.getInstance().getExecutor().logException(e);
|
||||
return false;
|
||||
}
|
||||
|
||||
try(ResultSet result = query("SELECT * FROM whitelist " +
|
||||
"WHERE minimum >= ? AND maximum <= ?", start, end)) {
|
||||
return result.next();
|
||||
} catch (SQLException e) {
|
||||
AntiVPN.getInstance().getExecutor().logException(e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addWhitelist(UUID uuid) {
|
||||
try {
|
||||
statement("INSERT INTO whitelist (uuid) VALUES (?)", uuid.toString());
|
||||
} catch (SQLException e) {
|
||||
AntiVPN.getInstance().getExecutor().logException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addWhitelist(String cidr) {
|
||||
CIDRUtils cidrUtils;
|
||||
BigDecimal start, end;
|
||||
try {
|
||||
cidrUtils = new CIDRUtils(cidr);
|
||||
|
||||
start = IpUtils.getIpDecimal(cidrUtils.getStartAddress().getHostAddress()).orElseThrow();
|
||||
end = IpUtils.getIpDecimal(cidrUtils.getEndAddress().getHostAddress()).orElseThrow();
|
||||
} catch (UnknownHostException e) {
|
||||
AntiVPN.getInstance().getExecutor().logException(e);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
statement("INSERT INTO whitelist (minimum, maximum) VALUES (?, ?)", start, end);
|
||||
} catch (SQLException e) {
|
||||
AntiVPN.getInstance().getExecutor().logException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeWhitelist(UUID uuid) {
|
||||
try {
|
||||
statement("DELETE FROM whitelist WHERE uuid = ?", uuid.toString());
|
||||
} catch (SQLException e) {
|
||||
AntiVPN.getInstance().getExecutor().logException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeWhitelist(String cidr) {
|
||||
CIDRUtils cidrUtils;
|
||||
BigDecimal start, end;
|
||||
try {
|
||||
cidrUtils = new CIDRUtils(cidr);
|
||||
|
||||
start = IpUtils.getIpDecimal(cidrUtils.getStartAddress().getHostAddress()).orElseThrow();
|
||||
end = IpUtils.getIpDecimal(cidrUtils.getEndAddress().getHostAddress()).orElseThrow();
|
||||
} catch (UnknownHostException e) {
|
||||
AntiVPN.getInstance().getExecutor().logException(e);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
statement("DELETE FROM whitelist WHERE minimum = ? AND maximum = ?", start, end);
|
||||
} catch (SQLException e) {
|
||||
AntiVPN.getInstance().getExecutor().logException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getAlertsState(UUID uuid) {
|
||||
try(ResultSet result = query("SELECT * FROM alerts WHERE uuid = ?", uuid.toString())) {
|
||||
return result.next();
|
||||
} catch (SQLException e) {
|
||||
AntiVPN.getInstance().getExecutor().logException(e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAlertsState(UUID uuid, boolean state) {
|
||||
try {
|
||||
statement("INSERT INTO alerts (uuid, STATE) VALUES (?, ?) ON CONFLICT(uuid) DO UPDATE SET STATE = ?",
|
||||
uuid.toString(), state, state);
|
||||
} catch (SQLException e) {
|
||||
AntiVPN.getInstance().getExecutor().logException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
String url = "jdbc:sqlite:./plugins/AntiVPN/database.db";
|
||||
|
||||
try {
|
||||
Connection connection = DriverManager.getConnection(url);
|
||||
Statement statement = connection.createStatement();
|
||||
statement.execute("CREATE TABLE IF NOT EXISTS vpn_responses (ip TEXT, response TEXT)");
|
||||
statement.execute("CREATE TABLE IF NOT EXISTS whitelist (uuid TEXT, NUMBER minimum, NUMBER maximum)");
|
||||
statement.execute("CREATE TABLE IF NOT EXISTS alerts (uuid TEXT)");
|
||||
statement.execute("CREATE TABLE IF NOT EXISTS version (PRIMARY KEY(version) NUMBER, updated STATE)");
|
||||
|
||||
this.connection = connection;
|
||||
|
||||
// Run through updates
|
||||
for (Version version : Version.versions) {
|
||||
try(ResultSet result = query("SELECT * FROM version WHERE version = ?",
|
||||
version.versionNumber())) {
|
||||
if(!result.next()) {
|
||||
version.update(this);
|
||||
statement("INSERT INTO version (version, updated) VALUES (?, ?)",
|
||||
version.versionNumber(), true);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
AntiVPN.getInstance().getExecutor().logException(e);
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
AntiVPN.getInstance().getExecutor().logException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() {
|
||||
try {
|
||||
connection.close();
|
||||
} catch (SQLException e) {
|
||||
AntiVPN.getInstance().getExecutor().logException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private ResultSet query(@Language("SQL") String query, Object... args) throws SQLException {
|
||||
PreparedStatement pstmt = connection.prepareStatement(query);
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
pstmt.setObject(i + 1, args[i]);
|
||||
}
|
||||
|
||||
return pstmt.executeQuery();
|
||||
}
|
||||
|
||||
public void statement(@Language("SQL") String query, Object... args) throws SQLException {
|
||||
PreparedStatement pstmt = connection.prepareStatement(query);
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
pstmt.setObject(i + 1, args[i]);
|
||||
}
|
||||
|
||||
pstmt.execute();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package dev.brighten.antivpn.database.sqllite.version;
|
||||
|
||||
import dev.brighten.antivpn.database.sqllite.LiteDatabase;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public interface Version {
|
||||
void update(LiteDatabase database) throws SQLException;
|
||||
int versionNumber();
|
||||
|
||||
List<Version> versions = new ArrayList<>();
|
||||
|
||||
static void register(Version version) {
|
||||
versions.add(version);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package dev.brighten.antivpn.database.sqllite.version.impl;
|
||||
|
||||
import dev.brighten.antivpn.database.sqllite.LiteDatabase;
|
||||
import dev.brighten.antivpn.database.sqllite.version.Version;
|
||||
|
||||
public class First implements Version {
|
||||
|
||||
@Override
|
||||
public void update(LiteDatabase database) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int versionNumber() {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2013 Edin Dazdarevic (edin.dazdarevic@gmail.com)
|
||||
|
||||
* 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 dev.brighten.antivpn.utils;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A class that enables to get an IP range from CIDR specification. It supports
|
||||
* both IPv4 and IPv6.
|
||||
*/
|
||||
@Getter
|
||||
public class CIDRUtils {
|
||||
private final String cidr;
|
||||
|
||||
private final InetAddress inetAddress;
|
||||
|
||||
private InetAddress startAddress;
|
||||
private InetAddress endAddress;
|
||||
private final int prefixLength;
|
||||
|
||||
|
||||
public CIDRUtils(String cidr) throws UnknownHostException {
|
||||
|
||||
this.cidr = cidr;
|
||||
|
||||
/* split CIDR to address and prefix part */
|
||||
if (this.cidr.contains("/")) {
|
||||
int index = this.cidr.indexOf("/");
|
||||
String addressPart = this.cidr.substring(0, index);
|
||||
String networkPart = this.cidr.substring(index + 1);
|
||||
|
||||
inetAddress = InetAddress.getByName(addressPart);
|
||||
prefixLength = Integer.parseInt(networkPart);
|
||||
|
||||
calculate();
|
||||
} else {
|
||||
throw new IllegalArgumentException("not an valid CIDR format!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void calculate() throws UnknownHostException {
|
||||
|
||||
ByteBuffer maskBuffer;
|
||||
int targetSize;
|
||||
if (inetAddress.getAddress().length == 4) {
|
||||
maskBuffer =
|
||||
ByteBuffer
|
||||
.allocate(4)
|
||||
.putInt(-1);
|
||||
targetSize = 4;
|
||||
} else {
|
||||
maskBuffer = ByteBuffer.allocate(16)
|
||||
.putLong(-1L)
|
||||
.putLong(-1L);
|
||||
targetSize = 16;
|
||||
}
|
||||
|
||||
BigInteger mask = (new BigInteger(1, maskBuffer.array())).not().shiftRight(prefixLength);
|
||||
|
||||
ByteBuffer buffer = ByteBuffer.wrap(inetAddress.getAddress());
|
||||
BigInteger ipVal = new BigInteger(1, buffer.array());
|
||||
|
||||
BigInteger startIp = ipVal.and(mask);
|
||||
BigInteger endIp = startIp.add(mask.not());
|
||||
|
||||
byte[] startIpArr = toBytes(startIp.toByteArray(), targetSize);
|
||||
byte[] endIpArr = toBytes(endIp.toByteArray(), targetSize);
|
||||
|
||||
this.startAddress = InetAddress.getByAddress(startIpArr);
|
||||
this.endAddress = InetAddress.getByAddress(endIpArr);
|
||||
|
||||
}
|
||||
|
||||
private byte[] toBytes(byte[] array, int targetSize) {
|
||||
int counter = 0;
|
||||
List<Byte> newArr = new ArrayList<Byte>();
|
||||
while (counter < targetSize && (array.length - 1 - counter >= 0)) {
|
||||
newArr.add(0, array[array.length - 1 - counter]);
|
||||
counter++;
|
||||
}
|
||||
|
||||
int size = newArr.size();
|
||||
for (int i = 0; i < (targetSize - size); i++) {
|
||||
|
||||
newArr.add(0, (byte) 0);
|
||||
}
|
||||
|
||||
byte[] ret = new byte[newArr.size()];
|
||||
for (int i = 0; i < newArr.size(); i++) {
|
||||
ret[i] = newArr.get(i);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public String getNetworkAddress() {
|
||||
|
||||
return this.startAddress.getHostAddress();
|
||||
}
|
||||
|
||||
public String getBroadcastAddress() {
|
||||
return this.endAddress.getHostAddress();
|
||||
}
|
||||
|
||||
public boolean isInRange(String ipAddress) throws UnknownHostException {
|
||||
InetAddress address = InetAddress.getByName(ipAddress);
|
||||
BigInteger start = new BigInteger(1, this.startAddress.getAddress());
|
||||
BigInteger end = new BigInteger(1, this.endAddress.getAddress());
|
||||
BigInteger target = new BigInteger(1, address.getAddress());
|
||||
|
||||
int st = start.compareTo(target);
|
||||
int te = target.compareTo(end);
|
||||
|
||||
return (st == -1 || st == 0) && (te == -1 || te == 0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package dev.brighten.antivpn.utils;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.net.Inet4Address;
|
||||
import java.net.Inet6Address;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Optional;
|
||||
|
||||
public class IpUtils {
|
||||
public static Optional<BigDecimal> getIpDecimal(String address) {
|
||||
try {
|
||||
InetAddress inet = InetAddress.getByName(address);
|
||||
|
||||
if(inet instanceof Inet4Address) {
|
||||
return Optional.of(BigDecimal.valueOf(ipv4ToLong(address)));
|
||||
} return Optional.of(new BigDecimal(ipv6ToDecimalFormat(address)));
|
||||
} catch(Exception e) {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
public static long ipv4ToLong(String address) {
|
||||
String[] addrArray = address.split("\\.");
|
||||
|
||||
long ipDecimal = 0;
|
||||
|
||||
for (int i = 0; i < addrArray.length; i++) {
|
||||
|
||||
int power = 3 - i;
|
||||
ipDecimal += ((Integer.parseInt(addrArray[i]) % 256 * Math.pow(256, power)));
|
||||
}
|
||||
|
||||
return ipDecimal;
|
||||
}
|
||||
|
||||
public static String getIpv4(long ip) {
|
||||
StringBuilder sb = new StringBuilder(15);
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
sb.insert(0, ip & 0xff);
|
||||
|
||||
if (i < 3) {
|
||||
sb.insert(0, '.');
|
||||
}
|
||||
|
||||
ip >>= 8;
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static boolean isIpv4(BigDecimal ip) {
|
||||
return ip.compareTo(BigDecimal.valueOf(4294967295L)) <= 0;
|
||||
}
|
||||
|
||||
public static boolean isIpv6(BigDecimal ip) {
|
||||
return ip.compareTo(BigDecimal.valueOf(4294967295L)) > 0;
|
||||
}
|
||||
public static boolean isIpv4(String ip) {
|
||||
return ip.matches("^(?:[0-9]{1,3}\\.){3}[0-9]{1,3}$");
|
||||
}
|
||||
|
||||
public static boolean isNotIp(String ip) {
|
||||
return !isIpv4(ip) && !isIpv6(ip);
|
||||
}
|
||||
|
||||
public static boolean isIpv6(String ip) {
|
||||
return ip.matches("^([0-9a-fA-F]{1,4}:){7}([0-9a-fA-F]{1,4}|:)$|^(([0-9a-fA-F]{1,4}:){0,6}([0-9a-fA-F]{1,4}|:))?(::([0-9a-fA-F]{1,4}:){0,5}([0-9a-fA-F]{1,4}|:))?$");
|
||||
}
|
||||
|
||||
public static String getIpv4(BigDecimal ip) {
|
||||
try {
|
||||
return Inet4Address.getByAddress(ip.toBigInteger().toByteArray()).getHostAddress();
|
||||
} catch (UnknownHostException e) {
|
||||
return "Error";
|
||||
}
|
||||
}
|
||||
|
||||
public static String getIpv6(BigDecimal ip) {
|
||||
try {
|
||||
return Inet6Address.getByAddress(ip.toBigInteger().toByteArray()).getHostAddress();
|
||||
} catch (UnknownHostException e) {
|
||||
return "Error";
|
||||
}
|
||||
}
|
||||
|
||||
public static BigInteger ipv6ToDecimalFormat(String ipAddress) throws UnknownHostException {
|
||||
return new BigInteger(1, Inet6Address.getByName(ipAddress).getAddress());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,11 @@
|
||||
package dev.brighten.antivpn.utils;
|
||||
|
||||
import dev.brighten.antivpn.AntiVPN;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
public class StringUtil {
|
||||
public static String line(String color) {
|
||||
return color + "&m-----------------------------------------------------";
|
||||
@@ -9,7 +15,22 @@ public class StringUtil {
|
||||
return "&m-----------------------------------------------------";
|
||||
}
|
||||
|
||||
public static String lineNoStrike(String color) {
|
||||
return color + "-----------------------------------------------------";
|
||||
public static String getHash(String input) {
|
||||
try {
|
||||
MessageDigest digest = MessageDigest.getInstance("SHA-128");
|
||||
byte[] hash = digest.digest(input.getBytes(StandardCharsets.UTF_8));
|
||||
StringBuilder hexString = new StringBuilder(2 * hash.length);
|
||||
for (byte b : hash) {
|
||||
String hex = Integer.toHexString(0xff & b);
|
||||
if (hex.length() == 1) {
|
||||
hexString.append('0');
|
||||
}
|
||||
hexString.append(hex);
|
||||
}
|
||||
return hexString.toString();
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
AntiVPN.getInstance().getExecutor().logException(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user