mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2025-03-02 11:11:21 +01:00
Added Untrusted-annotation to be more careful around user given data
- Fixed SQL-injection vulnerability in an endpoint - Fixed XSS on Whitelist deny 403 page - Fixed XSS on Internal Error 500 page if untrusted data ends up in exception message
This commit is contained in:
parent
82274ae658
commit
38785a9505
@ -19,6 +19,7 @@ package com.djrapitops.plan.addons.placeholderapi;
|
|||||||
import com.djrapitops.plan.PlanSystem;
|
import com.djrapitops.plan.PlanSystem;
|
||||||
import com.djrapitops.plan.placeholder.PlanPlaceholders;
|
import com.djrapitops.plan.placeholder.PlanPlaceholders;
|
||||||
import com.djrapitops.plan.processing.Processing;
|
import com.djrapitops.plan.processing.Processing;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
import com.djrapitops.plan.utilities.logging.ErrorContext;
|
import com.djrapitops.plan.utilities.logging.ErrorContext;
|
||||||
import com.djrapitops.plan.utilities.logging.ErrorLogger;
|
import com.djrapitops.plan.utilities.logging.ErrorLogger;
|
||||||
import com.djrapitops.plan.version.VersionChecker;
|
import com.djrapitops.plan.version.VersionChecker;
|
||||||
@ -89,7 +90,7 @@ public class PlanPlaceholderExtension extends PlaceholderExpansion {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String onRequest(OfflinePlayer player, String params) {
|
public String onRequest(OfflinePlayer player, @Untrusted String params) {
|
||||||
UUID uuid = player != null ? player.getUniqueId() : null;
|
UUID uuid = player != null ? player.getUniqueId() : null;
|
||||||
if ("Server thread".equalsIgnoreCase(Thread.currentThread().getName())) {
|
if ("Server thread".equalsIgnoreCase(Thread.currentThread().getName())) {
|
||||||
return getCached(params, uuid);
|
return getCached(params, uuid);
|
||||||
@ -97,7 +98,7 @@ public class PlanPlaceholderExtension extends PlaceholderExpansion {
|
|||||||
return getPlaceholderValue(params, uuid);
|
return getPlaceholderValue(params, uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getPlaceholderValue(String params, UUID uuid) {
|
private String getPlaceholderValue(@Untrusted String params, UUID uuid) {
|
||||||
try {
|
try {
|
||||||
String value = placeholders.onPlaceholderRequest(uuid, parseRequest(params), parseParameters(params));
|
String value = placeholders.onPlaceholderRequest(uuid, parseRequest(params), parseParameters(params));
|
||||||
|
|
||||||
@ -114,14 +115,16 @@ public class PlanPlaceholderExtension extends PlaceholderExpansion {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String parseRequest(String params) {
|
@Untrusted
|
||||||
|
private String parseRequest(@Untrusted String params) {
|
||||||
return params.split(":")[0];
|
return params.split(":")[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<String> parseParameters(String params) {
|
@Untrusted
|
||||||
|
private List<String> parseParameters(@Untrusted String params) {
|
||||||
List<String> parameters = new ArrayList<>();
|
List<String> parameters = new ArrayList<>();
|
||||||
boolean first = true;
|
boolean first = true;
|
||||||
for (String parameter : params.split(":")) {
|
for (@Untrusted String parameter : params.split(":")) {
|
||||||
if (first) {
|
if (first) {
|
||||||
first = false;
|
first = false;
|
||||||
} else {
|
} else {
|
||||||
@ -131,8 +134,8 @@ public class PlanPlaceholderExtension extends PlaceholderExpansion {
|
|||||||
return parameters;
|
return parameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getCached(String params, UUID uuid) {
|
private String getCached(@Untrusted String params, UUID uuid) {
|
||||||
String key = params + "-" + uuid;
|
@Untrusted String key = params + "-" + uuid;
|
||||||
|
|
||||||
if (!currentlyProcessing.contains(key)) {
|
if (!currentlyProcessing.contains(key)) {
|
||||||
currentlyProcessing.add(key);
|
currentlyProcessing.add(key);
|
||||||
|
@ -24,6 +24,7 @@ import com.djrapitops.plan.settings.locale.Locale;
|
|||||||
import com.djrapitops.plan.settings.locale.lang.DeepHelpLang;
|
import com.djrapitops.plan.settings.locale.lang.DeepHelpLang;
|
||||||
import com.djrapitops.plan.settings.locale.lang.HelpLang;
|
import com.djrapitops.plan.settings.locale.lang.HelpLang;
|
||||||
import com.djrapitops.plan.storage.database.DBType;
|
import com.djrapitops.plan.storage.database.DBType;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
import com.djrapitops.plan.utilities.logging.ErrorContext;
|
import com.djrapitops.plan.utilities.logging.ErrorContext;
|
||||||
import com.djrapitops.plan.utilities.logging.ErrorLogger;
|
import com.djrapitops.plan.utilities.logging.ErrorLogger;
|
||||||
|
|
||||||
@ -84,7 +85,7 @@ public class PlanCommand {
|
|||||||
this.errorLogger = errorLogger;
|
this.errorLogger = errorLogger;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleException(RuntimeException error, CMDSender sender, Arguments arguments) {
|
private void handleException(RuntimeException error, CMDSender sender, @Untrusted Arguments arguments) {
|
||||||
if (error instanceof IllegalArgumentException) {
|
if (error instanceof IllegalArgumentException) {
|
||||||
sender.send("§c" + error.getMessage());
|
sender.send("§c" + error.getMessage());
|
||||||
} else {
|
} else {
|
||||||
@ -131,13 +132,13 @@ public class PlanCommand {
|
|||||||
return command;
|
return command;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> serverNames(CMDSender sender, Arguments arguments) {
|
public List<String> serverNames(CMDSender sender, @Untrusted Arguments arguments) {
|
||||||
String asString = arguments.concatenate(" ");
|
@Untrusted String asString = arguments.concatenate(" ");
|
||||||
return tabCompleteCache.getMatchingServerIdentifiers(asString);
|
return tabCompleteCache.getMatchingServerIdentifiers(asString);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<String> playerNames(CMDSender sender, Arguments arguments) {
|
private List<String> playerNames(CMDSender sender, @Untrusted Arguments arguments) {
|
||||||
String asString = arguments.concatenate(" ");
|
@Untrusted String asString = arguments.concatenate(" ");
|
||||||
return tabCompleteCache.getMatchingPlayerIdentifiers(asString);
|
return tabCompleteCache.getMatchingPlayerIdentifiers(asString);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -254,12 +255,12 @@ public class PlanCommand {
|
|||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<String> webUserNames(CMDSender sender, Arguments arguments) {
|
private List<String> webUserNames(CMDSender sender, @Untrusted Arguments arguments) {
|
||||||
if (!sender.hasPermission(Permissions.UNREGISTER_OTHER)) {
|
if (!sender.hasPermission(Permissions.UNREGISTER_OTHER)) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
String username = arguments.concatenate(" ");
|
@Untrusted String username = arguments.concatenate(" ");
|
||||||
return tabCompleteCache.getMatchingUserIdentifiers(username);
|
return tabCompleteCache.getMatchingUserIdentifiers(username);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -388,15 +389,15 @@ public class PlanCommand {
|
|||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<String> getBackupFilenames(CMDSender sender, Arguments arguments) {
|
private List<String> getBackupFilenames(CMDSender sender, @Untrusted Arguments arguments) {
|
||||||
if (arguments.get(1).isPresent()) {
|
if (arguments.get(1).isPresent()) {
|
||||||
return DBType.names();
|
return DBType.names();
|
||||||
}
|
}
|
||||||
Optional<String> firstArgument = arguments.get(0);
|
@Untrusted Optional<String> firstArgument = arguments.get(0);
|
||||||
if (firstArgument.isEmpty()) {
|
if (firstArgument.isEmpty()) {
|
||||||
return tabCompleteCache.getMatchingBackupFilenames(null);
|
return tabCompleteCache.getMatchingBackupFilenames(null);
|
||||||
}
|
}
|
||||||
String part = firstArgument.get();
|
@Untrusted String part = firstArgument.get();
|
||||||
return tabCompleteCache.getMatchingBackupFilenames(part);
|
return tabCompleteCache.getMatchingBackupFilenames(part);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@ import com.djrapitops.plan.storage.database.queries.objects.ServerQueries;
|
|||||||
import com.djrapitops.plan.storage.database.queries.objects.UserIdentifierQueries;
|
import com.djrapitops.plan.storage.database.queries.objects.UserIdentifierQueries;
|
||||||
import com.djrapitops.plan.storage.database.queries.objects.WebUserQueries;
|
import com.djrapitops.plan.storage.database.queries.objects.WebUserQueries;
|
||||||
import com.djrapitops.plan.storage.file.PlanFiles;
|
import com.djrapitops.plan.storage.file.PlanFiles;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
@ -115,25 +116,25 @@ public class TabCompleteCache implements SubSystem {
|
|||||||
backupFileNames.clear();
|
backupFileNames.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> getMatchingServerIdentifiers(String searchFor) {
|
public List<String> getMatchingServerIdentifiers(@Untrusted String searchFor) {
|
||||||
return findMatches(serverIdentifiers, searchFor);
|
return findMatches(serverIdentifiers, searchFor);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> getMatchingPlayerIdentifiers(String searchFor) {
|
public List<String> getMatchingPlayerIdentifiers(@Untrusted String searchFor) {
|
||||||
playerIdentifiers.addAll(serverSensor.getOnlinePlayerNames());
|
playerIdentifiers.addAll(serverSensor.getOnlinePlayerNames());
|
||||||
return findMatches(playerIdentifiers, searchFor);
|
return findMatches(playerIdentifiers, searchFor);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> getMatchingUserIdentifiers(String searchFor) {
|
public List<String> getMatchingUserIdentifiers(@Untrusted String searchFor) {
|
||||||
return findMatches(userIdentifiers, searchFor);
|
return findMatches(userIdentifiers, searchFor);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> getMatchingBackupFilenames(String searchFor) {
|
public List<String> getMatchingBackupFilenames(@Untrusted String searchFor) {
|
||||||
return findMatches(backupFileNames, searchFor);
|
return findMatches(backupFileNames, searchFor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
List<String> findMatches(Collection<String> searchList, String searchFor) {
|
List<String> findMatches(Collection<String> searchList, @Untrusted String searchFor) {
|
||||||
List<String> filtered = searchList.stream()
|
List<String> filtered = searchList.stream()
|
||||||
.filter(identifier -> searchFor == null || searchFor.isEmpty() || identifier.startsWith(searchFor))
|
.filter(identifier -> searchFor == null || searchFor.isEmpty() || identifier.startsWith(searchFor))
|
||||||
.sorted(String.CASE_INSENSITIVE_ORDER)
|
.sorted(String.CASE_INSENSITIVE_ORDER)
|
||||||
|
@ -46,6 +46,7 @@ import com.djrapitops.plan.storage.database.DBSystem;
|
|||||||
import com.djrapitops.plan.storage.database.Database;
|
import com.djrapitops.plan.storage.database.Database;
|
||||||
import com.djrapitops.plan.storage.database.queries.containers.ContainerFetchQueries;
|
import com.djrapitops.plan.storage.database.queries.containers.ContainerFetchQueries;
|
||||||
import com.djrapitops.plan.storage.database.queries.objects.UserIdentifierQueries;
|
import com.djrapitops.plan.storage.database.queries.objects.UserIdentifierQueries;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
@ -95,8 +96,8 @@ public class DataUtilityCommands {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onExport(CMDSender sender, Arguments arguments) {
|
public void onExport(CMDSender sender, @Untrusted Arguments arguments) {
|
||||||
String exportKind = arguments.get(0)
|
@Untrusted String exportKind = arguments.get(0)
|
||||||
.orElseThrow(() -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_ACCEPTS_ARGUMENTS, locale.getString(HelpLang.ARG_EXPORT_KIND), "players, server_json")));
|
.orElseThrow(() -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_ACCEPTS_ARGUMENTS, locale.getString(HelpLang.ARG_EXPORT_KIND), "players, server_json")));
|
||||||
|
|
||||||
ensureDatabaseIsOpen();
|
ensureDatabaseIsOpen();
|
||||||
@ -104,7 +105,7 @@ public class DataUtilityCommands {
|
|||||||
getExportFunction(exportKind).accept(sender);
|
getExportFunction(exportKind).accept(sender);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Consumer<CMDSender> getExportFunction(String exportArg) {
|
private Consumer<CMDSender> getExportFunction(@Untrusted String exportArg) {
|
||||||
if ("players".equals(exportArg)) {
|
if ("players".equals(exportArg)) {
|
||||||
return this::exportPlayers;
|
return this::exportPlayers;
|
||||||
} else if ("server_json".endsWith(exportArg)) {
|
} else if ("server_json".endsWith(exportArg)) {
|
||||||
@ -176,8 +177,8 @@ public class DataUtilityCommands {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onImport(CMDSender sender, Arguments arguments) {
|
public void onImport(CMDSender sender, @Untrusted Arguments arguments) {
|
||||||
String importKind = arguments.get(0)
|
@Untrusted String importKind = arguments.get(0)
|
||||||
.orElseThrow(() -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_ACCEPTS_ARGUMENTS, locale.getString(HelpLang.ARG_IMPORT_KIND), importSystem.getImporterNames().toString())));
|
.orElseThrow(() -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_ACCEPTS_ARGUMENTS, locale.getString(HelpLang.ARG_IMPORT_KIND), importSystem.getImporterNames().toString())));
|
||||||
|
|
||||||
ensureDatabaseIsOpen();
|
ensureDatabaseIsOpen();
|
||||||
@ -185,7 +186,7 @@ public class DataUtilityCommands {
|
|||||||
findAndProcessImporter(sender, importKind);
|
findAndProcessImporter(sender, importKind);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void findAndProcessImporter(CMDSender sender, String importKind) {
|
private void findAndProcessImporter(CMDSender sender, @Untrusted String importKind) {
|
||||||
Optional<Importer> foundImporter = importSystem.getImporter(importKind);
|
Optional<Importer> foundImporter = importSystem.getImporter(importKind);
|
||||||
if (foundImporter.isPresent()) {
|
if (foundImporter.isPresent()) {
|
||||||
Importer importer = foundImporter.get();
|
Importer importer = foundImporter.get();
|
||||||
@ -199,8 +200,8 @@ public class DataUtilityCommands {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onSearch(CMDSender sender, Arguments arguments) {
|
public void onSearch(CMDSender sender, @Untrusted Arguments arguments) {
|
||||||
String searchingFor = arguments.concatenate(" ");
|
@Untrusted String searchingFor = arguments.concatenate(" ");
|
||||||
if (searchingFor.trim().isEmpty()) {
|
if (searchingFor.trim().isEmpty()) {
|
||||||
throw new IllegalArgumentException(locale.getString(CommandLang.FAIL_EMPTY_SEARCH_STRING));
|
throw new IllegalArgumentException(locale.getString(CommandLang.FAIL_EMPTY_SEARCH_STRING));
|
||||||
}
|
}
|
||||||
@ -221,8 +222,8 @@ public class DataUtilityCommands {
|
|||||||
sender.send(sender.getFormatter().table(asTableString.toString(), "::"));
|
sender.send(sender.getFormatter().table(asTableString.toString(), "::"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onInGame(CMDSender sender, Arguments arguments) {
|
public void onInGame(CMDSender sender, @Untrusted Arguments arguments) {
|
||||||
String identifier = arguments.concatenate(" ");
|
@Untrusted String identifier = arguments.concatenate(" ");
|
||||||
UUID playerUUID = identifiers.getPlayerUUID(identifier);
|
UUID playerUUID = identifiers.getPlayerUUID(identifier);
|
||||||
UUID senderUUID = sender.getUUID().orElse(null);
|
UUID senderUUID = sender.getUUID().orElse(null);
|
||||||
if (playerUUID == null) playerUUID = senderUUID;
|
if (playerUUID == null) playerUUID = senderUUID;
|
||||||
|
@ -46,6 +46,7 @@ import com.djrapitops.plan.storage.database.transactions.Transaction;
|
|||||||
import com.djrapitops.plan.storage.database.transactions.commands.*;
|
import com.djrapitops.plan.storage.database.transactions.commands.*;
|
||||||
import com.djrapitops.plan.storage.database.transactions.patches.BadFabricJoinAddressValuePatch;
|
import com.djrapitops.plan.storage.database.transactions.patches.BadFabricJoinAddressValuePatch;
|
||||||
import com.djrapitops.plan.storage.file.PlanFiles;
|
import com.djrapitops.plan.storage.file.PlanFiles;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
import com.djrapitops.plan.utilities.logging.ErrorContext;
|
import com.djrapitops.plan.utilities.logging.ErrorContext;
|
||||||
import com.djrapitops.plan.utilities.logging.ErrorLogger;
|
import com.djrapitops.plan.utilities.logging.ErrorLogger;
|
||||||
import net.playeranalytics.plugin.player.UUIDFetcher;
|
import net.playeranalytics.plugin.player.UUIDFetcher;
|
||||||
@ -113,7 +114,7 @@ public class DatabaseCommands {
|
|||||||
this.processing = processing;
|
this.processing = processing;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onBackup(CMDSender sender, Arguments arguments) {
|
public void onBackup(CMDSender sender, @Untrusted Arguments arguments) {
|
||||||
String dbName = arguments.get(0)
|
String dbName = arguments.get(0)
|
||||||
.orElse(dbSystem.getDatabase().getType().getName())
|
.orElse(dbSystem.getDatabase().getType().getName())
|
||||||
.toLowerCase();
|
.toLowerCase();
|
||||||
@ -129,7 +130,7 @@ public class DatabaseCommands {
|
|||||||
sender.send(locale.getString(CommandLang.PROGRESS_SUCCESS));
|
sender.send(locale.getString(CommandLang.PROGRESS_SUCCESS));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void performBackup(CMDSender sender, Arguments arguments, String dbName, Database fromDB) {
|
public void performBackup(CMDSender sender, @Untrusted Arguments arguments, String dbName, Database fromDB) {
|
||||||
Database toDB = null;
|
Database toDB = null;
|
||||||
try {
|
try {
|
||||||
String timeStamp = timestamp.apply(System.currentTimeMillis());
|
String timeStamp = timestamp.apply(System.currentTimeMillis());
|
||||||
@ -150,8 +151,8 @@ public class DatabaseCommands {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onRestore(String mainCommand, CMDSender sender, Arguments arguments) {
|
public void onRestore(String mainCommand, CMDSender sender, @Untrusted Arguments arguments) {
|
||||||
String backupDbName = arguments.get(0)
|
@Untrusted String backupDbName = arguments.get(0)
|
||||||
.orElseThrow(() -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_REQ_ARGS, 1, "<" + locale.getString(HelpLang.ARG_BACKUP_FILE) + ">")));
|
.orElseThrow(() -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_REQ_ARGS, 1, "<" + locale.getString(HelpLang.ARG_BACKUP_FILE) + ">")));
|
||||||
|
|
||||||
boolean containsDBFileExtension = backupDbName.endsWith(".db");
|
boolean containsDBFileExtension = backupDbName.endsWith(".db");
|
||||||
@ -219,7 +220,7 @@ public class DatabaseCommands {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onMove(String mainCommand, CMDSender sender, Arguments arguments) {
|
public void onMove(String mainCommand, CMDSender sender, @Untrusted Arguments arguments) {
|
||||||
DBType fromDB = arguments.get(0).flatMap(DBType::getForName)
|
DBType fromDB = arguments.get(0).flatMap(DBType::getForName)
|
||||||
.orElseThrow(() -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_INCORRECT_DB, arguments.get(0).orElse("<MySQL/SQLite>"))));
|
.orElseThrow(() -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_INCORRECT_DB, arguments.get(0).orElse("<MySQL/SQLite>"))));
|
||||||
|
|
||||||
@ -282,7 +283,7 @@ public class DatabaseCommands {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void onClear(String mainCommand, CMDSender sender, Arguments arguments) {
|
public void onClear(String mainCommand, CMDSender sender, @Untrusted Arguments arguments) {
|
||||||
DBType fromDB = arguments.get(0).flatMap(DBType::getForName)
|
DBType fromDB = arguments.get(0).flatMap(DBType::getForName)
|
||||||
.orElseThrow(() -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_INCORRECT_DB, arguments.get(0).orElse("<MySQL/SQLite>"))));
|
.orElseThrow(() -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_INCORRECT_DB, arguments.get(0).orElse("<MySQL/SQLite>"))));
|
||||||
|
|
||||||
@ -335,8 +336,8 @@ public class DatabaseCommands {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onFixFabricJoinAddresses(String mainCommand, CMDSender sender, Arguments arguments) {
|
public void onFixFabricJoinAddresses(String mainCommand, CMDSender sender, @Untrusted Arguments arguments) {
|
||||||
String identifier = arguments.concatenate(" ");
|
@Untrusted String identifier = arguments.concatenate(" ");
|
||||||
Optional<ServerUUID> serverUUID = identifiers.getServerUUID(identifier);
|
Optional<ServerUUID> serverUUID = identifiers.getServerUUID(identifier);
|
||||||
if (serverUUID.isEmpty()) {
|
if (serverUUID.isEmpty()) {
|
||||||
throw new IllegalArgumentException(locale.getString(CommandLang.FAIL_SERVER_NOT_FOUND, identifier));
|
throw new IllegalArgumentException(locale.getString(CommandLang.FAIL_SERVER_NOT_FOUND, identifier));
|
||||||
@ -385,8 +386,8 @@ public class DatabaseCommands {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onRemove(String mainCommand, CMDSender sender, Arguments arguments) {
|
public void onRemove(String mainCommand, CMDSender sender, @Untrusted Arguments arguments) {
|
||||||
String identifier = arguments.concatenate(" ");
|
@Untrusted String identifier = arguments.concatenate(" ");
|
||||||
UUID playerUUID = identifiers.getPlayerUUID(identifier);
|
UUID playerUUID = identifiers.getPlayerUUID(identifier);
|
||||||
if (playerUUID == null) {
|
if (playerUUID == null) {
|
||||||
throw new IllegalArgumentException(locale.getString(CommandLang.FAIL_PLAYER_NOT_FOUND, identifier));
|
throw new IllegalArgumentException(locale.getString(CommandLang.FAIL_PLAYER_NOT_FOUND, identifier));
|
||||||
@ -444,9 +445,9 @@ public class DatabaseCommands {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onUninstalled(CMDSender sender, Arguments arguments) {
|
public void onUninstalled(CMDSender sender, @Untrusted Arguments arguments) {
|
||||||
ensureDatabaseIsOpen();
|
ensureDatabaseIsOpen();
|
||||||
String identifier = arguments.concatenate(" ");
|
@Untrusted String identifier = arguments.concatenate(" ");
|
||||||
Server server = dbSystem.getDatabase()
|
Server server = dbSystem.getDatabase()
|
||||||
.query(ServerQueries.fetchServerMatchingIdentifier(identifier))
|
.query(ServerQueries.fetchServerMatchingIdentifier(identifier))
|
||||||
.orElseThrow(() -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_SERVER_NOT_FOUND, identifier)));
|
.orElseThrow(() -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_SERVER_NOT_FOUND, identifier)));
|
||||||
@ -460,7 +461,7 @@ public class DatabaseCommands {
|
|||||||
sender.send(locale.getString(CommandLang.DB_UNINSTALLED));
|
sender.send(locale.getString(CommandLang.DB_UNINSTALLED));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onHotswap(CMDSender sender, Arguments arguments) {
|
public void onHotswap(CMDSender sender, @Untrusted Arguments arguments) {
|
||||||
DBType toDB = arguments.get(0).flatMap(DBType::getForName)
|
DBType toDB = arguments.get(0).flatMap(DBType::getForName)
|
||||||
.orElseThrow(() -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_INCORRECT_DB, arguments.get(0).orElse("<MySQL/SQLite>"))));
|
.orElseThrow(() -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_INCORRECT_DB, arguments.get(0).orElse("<MySQL/SQLite>"))));
|
||||||
|
|
||||||
@ -482,7 +483,7 @@ public class DatabaseCommands {
|
|||||||
statusCommands.onReload(sender);
|
statusCommands.onReload(sender);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onOnlineConversion(String mainCommand, CMDSender sender, Arguments arguments) {
|
public void onOnlineConversion(String mainCommand, CMDSender sender, @Untrusted Arguments arguments) {
|
||||||
boolean removeOfflinePlayers = arguments.get(0)
|
boolean removeOfflinePlayers = arguments.get(0)
|
||||||
.map("--remove_offline"::equals)
|
.map("--remove_offline"::equals)
|
||||||
.orElse(false);
|
.orElse(false);
|
||||||
@ -491,7 +492,7 @@ public class DatabaseCommands {
|
|||||||
Map<UUID, BaseUser> baseUsersByUUID = dbSystem.getDatabase().query(BaseUserQueries.fetchAllBaseUsersByUUID());
|
Map<UUID, BaseUser> baseUsersByUUID = dbSystem.getDatabase().query(BaseUserQueries.fetchAllBaseUsersByUUID());
|
||||||
List<String> playerNames = baseUsersByUUID.values().stream().map(BaseUser::getName).collect(Collectors.toList());
|
List<String> playerNames = baseUsersByUUID.values().stream().map(BaseUser::getName).collect(Collectors.toList());
|
||||||
sender.send("Performing lookup for " + playerNames.size() + " uuids from Mojang..");
|
sender.send("Performing lookup for " + playerNames.size() + " uuids from Mojang..");
|
||||||
sender.send("Preparation estimated complete at: " + clock.apply(System.currentTimeMillis() + playerNames.size() * 100) + " (due to request rate limiting)");
|
sender.send("Preparation estimated complete at: " + clock.apply(System.currentTimeMillis() + playerNames.size() * 100L) + " (due to request rate limiting)");
|
||||||
Map<String, UUID> onlineUUIDsOfPlayers = getUUIDViaUUIDFetcher(playerNames);
|
Map<String, UUID> onlineUUIDsOfPlayers = getUUIDViaUUIDFetcher(playerNames);
|
||||||
|
|
||||||
if (onlineUUIDsOfPlayers.isEmpty()) {
|
if (onlineUUIDsOfPlayers.isEmpty()) {
|
||||||
|
@ -33,6 +33,7 @@ import com.djrapitops.plan.storage.database.DBSystem;
|
|||||||
import com.djrapitops.plan.storage.database.Database;
|
import com.djrapitops.plan.storage.database.Database;
|
||||||
import com.djrapitops.plan.storage.database.queries.objects.ServerQueries;
|
import com.djrapitops.plan.storage.database.queries.objects.ServerQueries;
|
||||||
import com.djrapitops.plan.storage.database.queries.objects.WebUserQueries;
|
import com.djrapitops.plan.storage.database.queries.objects.WebUserQueries;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
@ -92,9 +93,9 @@ public class LinkCommands {
|
|||||||
* @param sender Sender of command.
|
* @param sender Sender of command.
|
||||||
* @param arguments Given arguments.
|
* @param arguments Given arguments.
|
||||||
*/
|
*/
|
||||||
public void onServerCommand(CMDSender sender, Arguments arguments) {
|
public void onServerCommand(CMDSender sender, @Untrusted Arguments arguments) {
|
||||||
Server server;
|
Server server;
|
||||||
String identifier = arguments.concatenate(" ");
|
@Untrusted String identifier = arguments.concatenate(" ");
|
||||||
if (arguments.isEmpty()) {
|
if (arguments.isEmpty()) {
|
||||||
server = serverInfo.getServer();
|
server = serverInfo.getServer();
|
||||||
} else {
|
} else {
|
||||||
@ -117,7 +118,7 @@ public class LinkCommands {
|
|||||||
* @param sender Sender of command.
|
* @param sender Sender of command.
|
||||||
* @param arguments Given arguments.
|
* @param arguments Given arguments.
|
||||||
*/
|
*/
|
||||||
public void onServersCommand(CMDSender sender, Arguments arguments) {
|
public void onServersCommand(CMDSender sender, @Untrusted Arguments arguments) {
|
||||||
ensureDatabaseIsOpen();
|
ensureDatabaseIsOpen();
|
||||||
String m = colors.getMainColor();
|
String m = colors.getMainColor();
|
||||||
String s = colors.getSecondaryColor();
|
String s = colors.getSecondaryColor();
|
||||||
@ -148,8 +149,8 @@ public class LinkCommands {
|
|||||||
* @param sender Sender of command.
|
* @param sender Sender of command.
|
||||||
* @param arguments Given arguments.
|
* @param arguments Given arguments.
|
||||||
*/
|
*/
|
||||||
public void onPlayerCommand(CMDSender sender, Arguments arguments) {
|
public void onPlayerCommand(CMDSender sender, @Untrusted Arguments arguments) {
|
||||||
String identifier = arguments.concatenate(" ");
|
@Untrusted String identifier = arguments.concatenate(" ");
|
||||||
UUID playerUUID = identifiers.getPlayerUUID(identifier);
|
UUID playerUUID = identifiers.getPlayerUUID(identifier);
|
||||||
UUID senderUUID = sender.getUUID().orElse(null);
|
UUID senderUUID = sender.getUUID().orElse(null);
|
||||||
if (playerUUID == null) playerUUID = senderUUID;
|
if (playerUUID == null) playerUUID = senderUUID;
|
||||||
@ -174,7 +175,7 @@ public class LinkCommands {
|
|||||||
* @param sender Sender of command
|
* @param sender Sender of command
|
||||||
* @param arguments Only present to fulfill Subcommand#onCommand requirements.
|
* @param arguments Only present to fulfill Subcommand#onCommand requirements.
|
||||||
*/
|
*/
|
||||||
public void onPlayersCommand(CMDSender sender, Arguments arguments) {
|
public void onPlayersCommand(CMDSender sender, @Untrusted Arguments arguments) {
|
||||||
String address = getAddress(sender) + "/players";
|
String address = getAddress(sender) + "/players";
|
||||||
sender.buildMessage()
|
sender.buildMessage()
|
||||||
.addPart(colors.getMainColor() + locale.getString(CommandLang.LINK_PLAYERS))
|
.addPart(colors.getMainColor() + locale.getString(CommandLang.LINK_PLAYERS))
|
||||||
@ -188,7 +189,7 @@ public class LinkCommands {
|
|||||||
* @param sender Sender of command
|
* @param sender Sender of command
|
||||||
* @param arguments Only present to fulfill Subcommand#onCommand requirements.
|
* @param arguments Only present to fulfill Subcommand#onCommand requirements.
|
||||||
*/
|
*/
|
||||||
public void onNetworkCommand(CMDSender sender, Arguments arguments) {
|
public void onNetworkCommand(CMDSender sender, @Untrusted Arguments arguments) {
|
||||||
String address = getAddress(sender) + "/network";
|
String address = getAddress(sender) + "/network";
|
||||||
sender.buildMessage()
|
sender.buildMessage()
|
||||||
.addPart(colors.getMainColor() + locale.getString(CommandLang.LINK_NETWORK))
|
.addPart(colors.getMainColor() + locale.getString(CommandLang.LINK_NETWORK))
|
||||||
@ -205,7 +206,7 @@ public class LinkCommands {
|
|||||||
* @param sender Sender of command.
|
* @param sender Sender of command.
|
||||||
* @param arguments Given arguments.
|
* @param arguments Given arguments.
|
||||||
*/
|
*/
|
||||||
public void onWebUsersCommand(CMDSender sender, Arguments arguments) {
|
public void onWebUsersCommand(CMDSender sender, @Untrusted Arguments arguments) {
|
||||||
ensureDatabaseIsOpen();
|
ensureDatabaseIsOpen();
|
||||||
String m = colors.getMainColor();
|
String m = colors.getMainColor();
|
||||||
String s = colors.getSecondaryColor();
|
String s = colors.getSecondaryColor();
|
||||||
@ -227,8 +228,8 @@ public class LinkCommands {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onJson(CMDSender sender, Arguments arguments) {
|
public void onJson(CMDSender sender, @Untrusted Arguments arguments) {
|
||||||
String identifier = arguments.concatenate(" ");
|
@Untrusted String identifier = arguments.concatenate(" ");
|
||||||
UUID playerUUID = identifiers.getPlayerUUID(identifier);
|
UUID playerUUID = identifiers.getPlayerUUID(identifier);
|
||||||
UUID senderUUID = sender.getUUID().orElse(null);
|
UUID senderUUID = sender.getUUID().orElse(null);
|
||||||
if (playerUUID == null) playerUUID = senderUUID;
|
if (playerUUID == null) playerUUID = senderUUID;
|
||||||
|
@ -26,6 +26,7 @@ import com.djrapitops.plan.settings.locale.lang.GenericLang;
|
|||||||
import com.djrapitops.plan.storage.database.DBSystem;
|
import com.djrapitops.plan.storage.database.DBSystem;
|
||||||
import com.djrapitops.plan.storage.database.Database;
|
import com.djrapitops.plan.storage.database.Database;
|
||||||
import com.djrapitops.plan.storage.database.queries.objects.ServerQueries;
|
import com.djrapitops.plan.storage.database.queries.objects.ServerQueries;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
import com.djrapitops.plan.utilities.logging.ErrorContext;
|
import com.djrapitops.plan.utilities.logging.ErrorContext;
|
||||||
import com.djrapitops.plan.utilities.logging.ErrorLogger;
|
import com.djrapitops.plan.utilities.logging.ErrorLogger;
|
||||||
import com.djrapitops.plan.version.VersionChecker;
|
import com.djrapitops.plan.version.VersionChecker;
|
||||||
@ -33,7 +34,6 @@ import net.playeranalytics.plugin.PluginInformation;
|
|||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public class PluginStatusCommands {
|
public class PluginStatusCommands {
|
||||||
@ -80,15 +80,15 @@ public class PluginStatusCommands {
|
|||||||
}, "Plan Reload Thread").start();
|
}, "Plan Reload Thread").start();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onDisable(CMDSender sender, Arguments arguments) {
|
public void onDisable(CMDSender sender, @Untrusted Arguments arguments) {
|
||||||
if (arguments.isEmpty()) {
|
if (arguments.isEmpty()) {
|
||||||
plugin.onDisable();
|
plugin.onDisable();
|
||||||
sender.send(locale.getString(CommandLang.DISABLE_DISABLED));
|
sender.send(locale.getString(CommandLang.DISABLE_DISABLED));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<String> kickCountDisable = arguments.get(0).filter("kickcount"::equalsIgnoreCase);
|
boolean kickCountDisable = arguments.get(0).map("kickcount"::equalsIgnoreCase).orElse(false);
|
||||||
if (kickCountDisable.isPresent()) {
|
if (kickCountDisable) {
|
||||||
status.setCountKicks(false);
|
status.setCountKicks(false);
|
||||||
sender.send(locale.getString(CommandLang.FEATURE_DISABLED, "Kick Counting"));
|
sender.send(locale.getString(CommandLang.FEATURE_DISABLED, "Kick Counting"));
|
||||||
} else {
|
} else {
|
||||||
|
@ -34,6 +34,7 @@ import com.djrapitops.plan.storage.database.queries.objects.WebUserQueries;
|
|||||||
import com.djrapitops.plan.storage.database.transactions.commands.RemoveWebUserTransaction;
|
import com.djrapitops.plan.storage.database.transactions.commands.RemoveWebUserTransaction;
|
||||||
import com.djrapitops.plan.storage.database.transactions.commands.StoreWebUserTransaction;
|
import com.djrapitops.plan.storage.database.transactions.commands.StoreWebUserTransaction;
|
||||||
import com.djrapitops.plan.utilities.PassEncryptUtil;
|
import com.djrapitops.plan.utilities.PassEncryptUtil;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
import com.djrapitops.plan.utilities.logging.ErrorContext;
|
import com.djrapitops.plan.utilities.logging.ErrorContext;
|
||||||
import com.djrapitops.plan.utilities.logging.ErrorLogger;
|
import com.djrapitops.plan.utilities.logging.ErrorLogger;
|
||||||
import net.playeranalytics.plugin.server.PluginLogger;
|
import net.playeranalytics.plugin.server.PluginLogger;
|
||||||
@ -87,7 +88,7 @@ public class RegistrationCommands {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onRegister(CMDSender sender, Arguments arguments) {
|
public void onRegister(CMDSender sender, @Untrusted Arguments arguments) {
|
||||||
ensureDatabaseIsOpen();
|
ensureDatabaseIsOpen();
|
||||||
if (arguments.isEmpty()) {
|
if (arguments.isEmpty()) {
|
||||||
String address = linkCommands.getAddress(sender) + "/register";
|
String address = linkCommands.getAddress(sender) + "/register";
|
||||||
@ -96,7 +97,7 @@ public class RegistrationCommands {
|
|||||||
.apply(builder -> linkCommands.linkTo(builder, sender, address))
|
.apply(builder -> linkCommands.linkTo(builder, sender, address))
|
||||||
.send();
|
.send();
|
||||||
} else {
|
} else {
|
||||||
Optional<String> code = arguments.getAfter("--code");
|
@Untrusted Optional<String> code = arguments.getAfter("--code");
|
||||||
if (code.isPresent()) {
|
if (code.isPresent()) {
|
||||||
registerUsingCode(sender, code.get());
|
registerUsingCode(sender, code.get());
|
||||||
} else {
|
} else {
|
||||||
@ -105,7 +106,7 @@ public class RegistrationCommands {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerUsingCode(CMDSender sender, String code) {
|
public void registerUsingCode(CMDSender sender, @Untrusted String code) {
|
||||||
UUID linkedToUUID = sender.getUUID().orElse(null);
|
UUID linkedToUUID = sender.getUUID().orElse(null);
|
||||||
Optional<User> user = RegistrationBin.register(code, linkedToUUID);
|
Optional<User> user = RegistrationBin.register(code, linkedToUUID);
|
||||||
if (user.isPresent()) {
|
if (user.isPresent()) {
|
||||||
@ -115,8 +116,8 @@ public class RegistrationCommands {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerUsingLegacy(CMDSender sender, Arguments arguments) {
|
public void registerUsingLegacy(CMDSender sender, @Untrusted Arguments arguments) {
|
||||||
String password = arguments.get(0)
|
@Untrusted String password = arguments.get(0)
|
||||||
.orElseThrow(() -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_REQ_ARGS, 1, "<password>")));
|
.orElseThrow(() -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_REQ_ARGS, 1, "<password>")));
|
||||||
String passwordHash = PassEncryptUtil.createHash(password);
|
String passwordHash = PassEncryptUtil.createHash(password);
|
||||||
int permissionLevel = arguments.getInteger(2)
|
int permissionLevel = arguments.getInteger(2)
|
||||||
@ -128,10 +129,10 @@ public class RegistrationCommands {
|
|||||||
if (senderUUID.isPresent() && senderName.isPresent()) {
|
if (senderUUID.isPresent() && senderName.isPresent()) {
|
||||||
String playerName = senderName.get();
|
String playerName = senderName.get();
|
||||||
UUID linkedToUUID = senderUUID.get();
|
UUID linkedToUUID = senderUUID.get();
|
||||||
String username = arguments.get(1).orElse(playerName);
|
@Untrusted String username = arguments.get(1).orElse(playerName);
|
||||||
registerUser(new User(username, playerName, linkedToUUID, passwordHash, permissionLevel, Collections.emptyList()), sender, permissionLevel);
|
registerUser(new User(username, playerName, linkedToUUID, passwordHash, permissionLevel, Collections.emptyList()), sender, permissionLevel);
|
||||||
} else {
|
} else {
|
||||||
String username = arguments.get(1)
|
@Untrusted String username = arguments.get(1)
|
||||||
.orElseThrow(() -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_REQ_ARGS, 3, "<password> <name> <level>")));
|
.orElseThrow(() -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_REQ_ARGS, 3, "<password> <name> <level>")));
|
||||||
registerUser(new User(username, "console", null, passwordHash, permissionLevel, Collections.emptyList()), sender, permissionLevel);
|
registerUser(new User(username, "console", null, passwordHash, permissionLevel, Collections.emptyList()), sender, permissionLevel);
|
||||||
}
|
}
|
||||||
@ -170,13 +171,13 @@ public class RegistrationCommands {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onUnregister(String mainCommand, CMDSender sender, Arguments arguments) {
|
public void onUnregister(String mainCommand, CMDSender sender, @Untrusted Arguments arguments) {
|
||||||
Optional<String> givenUsername = arguments.get(0).filter(arg -> sender.hasPermission(Permissions.UNREGISTER_OTHER));
|
@Untrusted Optional<String> givenUsername = arguments.get(0).filter(arg -> sender.hasPermission(Permissions.UNREGISTER_OTHER));
|
||||||
|
|
||||||
Database database = dbSystem.getDatabase();
|
Database database = dbSystem.getDatabase();
|
||||||
UUID playerUUID = sender.getUUID().orElse(null);
|
UUID playerUUID = sender.getUUID().orElse(null);
|
||||||
|
|
||||||
String username;
|
@Untrusted String username;
|
||||||
if (givenUsername.isEmpty() && playerUUID != null) {
|
if (givenUsername.isEmpty() && playerUUID != null) {
|
||||||
username = database.query(WebUserQueries.fetchUser(playerUUID))
|
username = database.query(WebUserQueries.fetchUser(playerUUID))
|
||||||
.map(User::getUsername)
|
.map(User::getUsername)
|
||||||
@ -231,8 +232,8 @@ public class RegistrationCommands {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void onLogoutCommand(CMDSender sender, Arguments arguments) {
|
public void onLogoutCommand(CMDSender sender, @Untrusted Arguments arguments) {
|
||||||
String loggingOut = arguments.get(0)
|
@Untrusted String loggingOut = arguments.get(0)
|
||||||
.orElseThrow(() -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_REQ_ONE_ARG, locale.getString(HelpLang.ARG_USERNAME) + "/*")));
|
.orElseThrow(() -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_REQ_ONE_ARG, locale.getString(HelpLang.ARG_USERNAME) + "/*")));
|
||||||
|
|
||||||
if ("*".equals(loggingOut)) {
|
if ("*".equals(loggingOut)) {
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.djrapitops.plan.commands.use;
|
package com.djrapitops.plan.commands.use;
|
||||||
|
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.commons.text.TextStringBuilder;
|
import org.apache.commons.text.TextStringBuilder;
|
||||||
|
|
||||||
@ -29,6 +30,7 @@ import java.util.Optional;
|
|||||||
*
|
*
|
||||||
* @author AuroraLS3
|
* @author AuroraLS3
|
||||||
*/
|
*/
|
||||||
|
@Untrusted
|
||||||
public class Arguments {
|
public class Arguments {
|
||||||
|
|
||||||
private final List<String> args;
|
private final List<String> args;
|
||||||
|
@ -18,6 +18,7 @@ package com.djrapitops.plan.commands.use;
|
|||||||
|
|
||||||
import com.djrapitops.plan.settings.locale.Locale;
|
import com.djrapitops.plan.settings.locale.Locale;
|
||||||
import com.djrapitops.plan.settings.locale.lang.CommandLang;
|
import com.djrapitops.plan.settings.locale.lang.CommandLang;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
import com.djrapitops.plan.utilities.java.TriConsumer;
|
import com.djrapitops.plan.utilities.java.TriConsumer;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -54,7 +55,7 @@ public class CommandWithSubcommands extends Subcommand {
|
|||||||
return subcommands;
|
return subcommands;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Optional<Subcommand> findSubCommand(Arguments arguments) {
|
public Optional<Subcommand> findSubCommand(@Untrusted Arguments arguments) {
|
||||||
return arguments.get(0).flatMap(alias -> {
|
return arguments.get(0).flatMap(alias -> {
|
||||||
for (Subcommand subcommand : subcommands) {
|
for (Subcommand subcommand : subcommands) {
|
||||||
if (subcommand.getAliases().contains(alias)) {
|
if (subcommand.getAliases().contains(alias)) {
|
||||||
@ -65,7 +66,7 @@ public class CommandWithSubcommands extends Subcommand {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onHelp(CMDSender sender, Arguments arguments) {
|
public void onHelp(CMDSender sender, @Untrusted Arguments arguments) {
|
||||||
List<Subcommand> hasPermissionFor = getPermittedSubcommands(sender);
|
List<Subcommand> hasPermissionFor = getPermittedSubcommands(sender);
|
||||||
sender.buildMessage()
|
sender.buildMessage()
|
||||||
.addPart(locale.getString(CommandLang.HEADER_HELP, getPrimaryAlias()))
|
.addPart(locale.getString(CommandLang.HEADER_HELP, getPrimaryAlias()))
|
||||||
@ -89,7 +90,7 @@ public class CommandWithSubcommands extends Subcommand {
|
|||||||
.send();
|
.send();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onCommand(CMDSender sender, Arguments arguments) {
|
public void onCommand(CMDSender sender, @Untrusted Arguments arguments) {
|
||||||
if (sender.isMissingPermissionsFor(this)) {
|
if (sender.isMissingPermissionsFor(this)) {
|
||||||
sender.send(locale.getString(CommandLang.FAIL_NO_PERMISSION) + " " + getRequiredPermissions());
|
sender.send(locale.getString(CommandLang.FAIL_NO_PERMISSION) + " " + getRequiredPermissions());
|
||||||
return;
|
return;
|
||||||
@ -101,10 +102,10 @@ public class CommandWithSubcommands extends Subcommand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void executeCommand(CMDSender sender, Arguments arguments) {
|
public void executeCommand(CMDSender sender, @Untrusted Arguments arguments) {
|
||||||
Optional<String> gotAlias = arguments.get(0);
|
@Untrusted Optional<String> gotAlias = arguments.get(0);
|
||||||
if (gotAlias.isPresent()) {
|
if (gotAlias.isPresent()) {
|
||||||
String alias = gotAlias.get();
|
@Untrusted String alias = gotAlias.get();
|
||||||
if ("help".equals(alias)) {
|
if ("help".equals(alias)) {
|
||||||
onHelp(sender, arguments);
|
onHelp(sender, arguments);
|
||||||
return;
|
return;
|
||||||
@ -128,8 +129,8 @@ public class CommandWithSubcommands extends Subcommand {
|
|||||||
fallback.accept(sender, arguments);
|
fallback.accept(sender, arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> onTabComplete(CMDSender sender, Arguments arguments) {
|
public List<String> onTabComplete(CMDSender sender, @Untrusted Arguments arguments) {
|
||||||
Optional<String> gotAlias = arguments.get(0);
|
@Untrusted Optional<String> gotAlias = arguments.get(0);
|
||||||
List<String> options = new ArrayList<>();
|
List<String> options = new ArrayList<>();
|
||||||
if (gotAlias.isPresent()) {
|
if (gotAlias.isPresent()) {
|
||||||
subcommandsLoop:
|
subcommandsLoop:
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
package com.djrapitops.plan.delivery.domain;
|
package com.djrapitops.plan.delivery.domain;
|
||||||
|
|
||||||
import com.djrapitops.plan.identification.ServerUUID;
|
import com.djrapitops.plan.identification.ServerUUID;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
@ -27,6 +28,7 @@ import java.util.Objects;
|
|||||||
*/
|
*/
|
||||||
public class Nickname implements DateHolder {
|
public class Nickname implements DateHolder {
|
||||||
|
|
||||||
|
@Untrusted
|
||||||
private final String name;
|
private final String name;
|
||||||
private final long date;
|
private final long date;
|
||||||
private final ServerUUID serverUUID;
|
private final ServerUUID serverUUID;
|
||||||
@ -37,6 +39,7 @@ public class Nickname implements DateHolder {
|
|||||||
this.serverUUID = serverUUID;
|
this.serverUUID = serverUUID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Untrusted
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name.length() <= 75 ? name : name.substring(0, 74);
|
return name.length() <= 75 ? name : name.substring(0, 74);
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ package com.djrapitops.plan.delivery.domain.auth;
|
|||||||
|
|
||||||
import com.djrapitops.plan.delivery.web.resolver.request.WebUser;
|
import com.djrapitops.plan.delivery.web.resolver.request.WebUser;
|
||||||
import com.djrapitops.plan.utilities.PassEncryptUtil;
|
import com.djrapitops.plan.utilities.PassEncryptUtil;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@ -30,6 +31,7 @@ import java.util.UUID;
|
|||||||
*/
|
*/
|
||||||
public class User implements Comparable<User> {
|
public class User implements Comparable<User> {
|
||||||
|
|
||||||
|
@Untrusted
|
||||||
private final String username;
|
private final String username;
|
||||||
private final String linkedTo;
|
private final String linkedTo;
|
||||||
private final UUID linkedToUUID; // null for 'console'
|
private final UUID linkedToUUID; // null for 'console'
|
||||||
@ -37,7 +39,7 @@ public class User implements Comparable<User> {
|
|||||||
private int permissionLevel;
|
private int permissionLevel;
|
||||||
private final Collection<String> permissions;
|
private final Collection<String> permissions;
|
||||||
|
|
||||||
public User(String username, String linkedTo, UUID linkedToUUID, String passwordHash, int permissionLevel, Collection<String> permissions) {
|
public User(@Untrusted String username, String linkedTo, UUID linkedToUUID, String passwordHash, int permissionLevel, Collection<String> permissions) {
|
||||||
this.username = username;
|
this.username = username;
|
||||||
this.linkedTo = linkedTo;
|
this.linkedTo = linkedTo;
|
||||||
this.linkedToUUID = linkedToUUID;
|
this.linkedToUUID = linkedToUUID;
|
||||||
@ -46,7 +48,7 @@ public class User implements Comparable<User> {
|
|||||||
this.permissions = permissions;
|
this.permissions = permissions;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean doesPasswordMatch(String password) {
|
public boolean doesPasswordMatch(@Untrusted String password) {
|
||||||
return PassEncryptUtil.verifyPassword(password, passwordHash);
|
return PassEncryptUtil.verifyPassword(password, passwordHash);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,6 +56,7 @@ public class User implements Comparable<User> {
|
|||||||
return new WebUser(linkedTo, linkedToUUID, username, permissions);
|
return new WebUser(linkedTo, linkedToUUID, username, permissions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Untrusted
|
||||||
public String getUsername() {
|
public String getUsername() {
|
||||||
return username;
|
return username;
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
package com.djrapitops.plan.delivery.domain.datatransfer;
|
package com.djrapitops.plan.delivery.domain.datatransfer;
|
||||||
|
|
||||||
import com.djrapitops.plan.storage.database.queries.filter.Filter;
|
import com.djrapitops.plan.storage.database.queries.filter.Filter;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
|
||||||
@ -28,6 +29,7 @@ import java.util.*;
|
|||||||
*
|
*
|
||||||
* @author AuroraLS3
|
* @author AuroraLS3
|
||||||
*/
|
*/
|
||||||
|
@Untrusted
|
||||||
public class InputFilterDto {
|
public class InputFilterDto {
|
||||||
|
|
||||||
private final String kind;
|
private final String kind;
|
||||||
@ -38,7 +40,7 @@ public class InputFilterDto {
|
|||||||
this.parameters = parameters;
|
this.parameters = parameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<InputFilterDto> parse(String json, Gson gson) throws IOException {
|
public static List<InputFilterDto> parse(@Untrusted String json, Gson gson) throws IOException {
|
||||||
return gson.getAdapter(new TypeToken<List<InputFilterDto>>() {}).fromJson(json);
|
return gson.getAdapter(new TypeToken<List<InputFilterDto>>() {}).fromJson(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,11 +16,14 @@
|
|||||||
*/
|
*/
|
||||||
package com.djrapitops.plan.delivery.domain.datatransfer;
|
package com.djrapitops.plan.delivery.domain.datatransfer;
|
||||||
|
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public class InputQueryDto {
|
public class InputQueryDto {
|
||||||
|
|
||||||
|
@Untrusted
|
||||||
public final List<InputFilterDto> filters;
|
public final List<InputFilterDto> filters;
|
||||||
private final ViewDto view;
|
private final ViewDto view;
|
||||||
|
|
||||||
@ -33,6 +36,7 @@ public class InputQueryDto {
|
|||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Untrusted
|
||||||
public List<InputFilterDto> getFilters() {
|
public List<InputFilterDto> getFilters() {
|
||||||
return filters;
|
return filters;
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ package com.djrapitops.plan.delivery.domain.datatransfer;
|
|||||||
import com.djrapitops.plan.delivery.formatting.Formatter;
|
import com.djrapitops.plan.delivery.formatting.Formatter;
|
||||||
import com.djrapitops.plan.delivery.formatting.Formatters;
|
import com.djrapitops.plan.delivery.formatting.Formatters;
|
||||||
import com.djrapitops.plan.identification.ServerUUID;
|
import com.djrapitops.plan.identification.ServerUUID;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
@ -31,6 +32,7 @@ import java.util.stream.Collectors;
|
|||||||
/**
|
/**
|
||||||
* Represents query page view that the user wants to see data for.
|
* Represents query page view that the user wants to see data for.
|
||||||
*/
|
*/
|
||||||
|
@Untrusted
|
||||||
public class ViewDto {
|
public class ViewDto {
|
||||||
private static final String DATE_PATTERN = "dd/MM/yyyy kk:mm";
|
private static final String DATE_PATTERN = "dd/MM/yyyy kk:mm";
|
||||||
|
|
||||||
|
@ -45,6 +45,7 @@ import com.djrapitops.plan.storage.database.queries.objects.*;
|
|||||||
import com.djrapitops.plan.storage.database.queries.objects.playertable.NetworkTablePlayersQuery;
|
import com.djrapitops.plan.storage.database.queries.objects.playertable.NetworkTablePlayersQuery;
|
||||||
import com.djrapitops.plan.storage.database.queries.objects.playertable.ServerTablePlayersQuery;
|
import com.djrapitops.plan.storage.database.queries.objects.playertable.ServerTablePlayersQuery;
|
||||||
import com.djrapitops.plan.utilities.comparators.SessionStartComparator;
|
import com.djrapitops.plan.utilities.comparators.SessionStartComparator;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
import com.djrapitops.plan.utilities.java.Maps;
|
import com.djrapitops.plan.utilities.java.Maps;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
@ -175,7 +176,7 @@ public class JSONFactory {
|
|||||||
return new PlayerKillMutator(kills).toJSONAsMap(formatters);
|
return new PlayerKillMutator(kills).toJSONAsMap(formatters);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Optional<ServerDto> serverForIdentifier(String identifier) {
|
public Optional<ServerDto> serverForIdentifier(@Untrusted String identifier) {
|
||||||
return dbSystem.getDatabase()
|
return dbSystem.getDatabase()
|
||||||
.query(ServerQueries.fetchServerMatchingIdentifier(identifier))
|
.query(ServerQueries.fetchServerMatchingIdentifier(identifier))
|
||||||
.map(ServerDto::fromServer);
|
.map(ServerDto::fromServer);
|
||||||
|
@ -21,7 +21,9 @@ import com.djrapitops.plan.delivery.rendering.html.Contributors;
|
|||||||
import com.djrapitops.plan.delivery.rendering.html.Html;
|
import com.djrapitops.plan.delivery.rendering.html.Html;
|
||||||
import com.djrapitops.plan.delivery.rendering.html.icon.Icon;
|
import com.djrapitops.plan.delivery.rendering.html.icon.Icon;
|
||||||
import com.djrapitops.plan.exceptions.ExceptionWithContext;
|
import com.djrapitops.plan.exceptions.ExceptionWithContext;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
import com.djrapitops.plan.version.VersionChecker;
|
import com.djrapitops.plan.version.VersionChecker;
|
||||||
|
import org.apache.commons.text.StringEscapeUtils;
|
||||||
import org.apache.commons.text.TextStringBuilder;
|
import org.apache.commons.text.TextStringBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -32,7 +34,9 @@ import org.apache.commons.text.TextStringBuilder;
|
|||||||
public class InternalErrorPage implements Page {
|
public class InternalErrorPage implements Page {
|
||||||
|
|
||||||
private final String template;
|
private final String template;
|
||||||
|
@Untrusted
|
||||||
private final String errorMsg;
|
private final String errorMsg;
|
||||||
|
@Untrusted
|
||||||
private final Throwable error;
|
private final Throwable error;
|
||||||
|
|
||||||
private final VersionChecker versionChecker;
|
private final VersionChecker versionChecker;
|
||||||
@ -66,13 +70,13 @@ public class InternalErrorPage implements Page {
|
|||||||
paragraph.append("Please report this issue here: ");
|
paragraph.append("Please report this issue here: ");
|
||||||
paragraph.append(Html.LINK.create("https://github.com/plan-player-analytics/Plan/issues", "Issues"));
|
paragraph.append(Html.LINK.create("https://github.com/plan-player-analytics/Plan/issues", "Issues"));
|
||||||
paragraph.append("<br><br><pre>");
|
paragraph.append("<br><br><pre>");
|
||||||
paragraph.append(error).append(" | ").append(errorMsg);
|
paragraph.append(StringEscapeUtils.escapeHtml4(error.toString())).append(" | ").append(StringEscapeUtils.escapeHtml4(errorMsg));
|
||||||
|
|
||||||
if (error instanceof ExceptionWithContext) {
|
if (error instanceof ExceptionWithContext) {
|
||||||
((ExceptionWithContext) error).getContext()
|
((ExceptionWithContext) error).getContext()
|
||||||
.ifPresent(context -> paragraph.append(context.getWhatToDo()
|
.ifPresent(context -> paragraph.append(context.getWhatToDo()
|
||||||
.map(whatToDo -> "<br>What to do about it: " + whatToDo)
|
.map(whatToDo -> "<br>What to do about it: " + whatToDo)
|
||||||
.orElse("<br>Error message: " + error.getMessage()))
|
.orElse("<br>Error message: " + StringEscapeUtils.escapeHtml4(error.getMessage())))
|
||||||
.append("<br><br>Related things:<br>")
|
.append("<br><br>Related things:<br>")
|
||||||
.appendWithSeparators(context.toLines(), "<br>")
|
.appendWithSeparators(context.toLines(), "<br>")
|
||||||
.append("<br>"));
|
.append("<br>"));
|
||||||
@ -91,8 +95,8 @@ public class InternalErrorPage implements Page {
|
|||||||
return paragraph.toString();
|
return paragraph.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void appendCause(Throwable cause, TextStringBuilder paragraph) {
|
private void appendCause(@Untrusted Throwable cause, TextStringBuilder paragraph) {
|
||||||
paragraph.append("<br>Caused by: ").append(cause);
|
paragraph.append("<br>Caused by: ").append(StringEscapeUtils.escapeHtml4(cause.toString()));
|
||||||
for (StackTraceElement element : cause.getStackTrace()) {
|
for (StackTraceElement element : cause.getStackTrace()) {
|
||||||
paragraph.append("<br>");
|
paragraph.append("<br>");
|
||||||
paragraph.append(" ").append(element);
|
paragraph.append(" ").append(element);
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
package com.djrapitops.plan.delivery.web;
|
package com.djrapitops.plan.delivery.web;
|
||||||
|
|
||||||
import com.djrapitops.plan.delivery.web.resolver.Resolver;
|
import com.djrapitops.plan.delivery.web.resolver.Resolver;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
@ -69,7 +70,7 @@ public class ResolverSvc implements ResolverService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Resolver> getResolvers(String target) {
|
public List<Resolver> getResolvers(@Untrusted String target) {
|
||||||
List<Resolver> resolvers = new ArrayList<>();
|
List<Resolver> resolvers = new ArrayList<>();
|
||||||
for (Container container : basicResolvers) {
|
for (Container container : basicResolvers) {
|
||||||
if (container.matcher.test(target)) resolvers.add(container.resolver);
|
if (container.matcher.test(target)) resolvers.add(container.resolver);
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.djrapitops.plan.delivery.webserver;
|
package com.djrapitops.plan.delivery.webserver;
|
||||||
|
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
import com.github.benmanes.caffeine.cache.Cache;
|
import com.github.benmanes.caffeine.cache.Cache;
|
||||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||||
|
|
||||||
@ -33,7 +34,7 @@ public class PassBruteForceGuard {
|
|||||||
.expireAfterWrite(90, TimeUnit.SECONDS)
|
.expireAfterWrite(90, TimeUnit.SECONDS)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
public boolean shouldPreventRequest(String accessor) {
|
public boolean shouldPreventRequest(@Untrusted String accessor) {
|
||||||
Integer attempts = failedLoginAttempts.getIfPresent(accessor);
|
Integer attempts = failedLoginAttempts.getIfPresent(accessor);
|
||||||
if (attempts == null) return false;
|
if (attempts == null) return false;
|
||||||
// Too many attempts, forbid further attempts.
|
// Too many attempts, forbid further attempts.
|
||||||
@ -41,7 +42,7 @@ public class PassBruteForceGuard {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Don't call on first connection.
|
// Don't call on first connection.
|
||||||
public void increaseAttemptCountOnFailedLogin(String accessor) {
|
public void increaseAttemptCountOnFailedLogin(@Untrusted String accessor) {
|
||||||
// Authentication was attempted, but failed so new attempt is going to be given if not forbidden
|
// Authentication was attempted, but failed so new attempt is going to be given if not forbidden
|
||||||
failedLoginAttempts.cleanUp();
|
failedLoginAttempts.cleanUp();
|
||||||
|
|
||||||
@ -59,7 +60,7 @@ public class PassBruteForceGuard {
|
|||||||
failedLoginAttempts.put(accessor, attempts + 1);
|
failedLoginAttempts.put(accessor, attempts + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void resetAttemptCount(String accessor) {
|
public void resetAttemptCount(@Untrusted String accessor) {
|
||||||
// Successful login
|
// Successful login
|
||||||
failedLoginAttempts.cleanUp();
|
failedLoginAttempts.cleanUp();
|
||||||
failedLoginAttempts.invalidate(accessor);
|
failedLoginAttempts.invalidate(accessor);
|
||||||
|
@ -18,6 +18,7 @@ package com.djrapitops.plan.delivery.webserver;
|
|||||||
|
|
||||||
import com.djrapitops.plan.delivery.web.resolver.request.Request;
|
import com.djrapitops.plan.delivery.web.resolver.request.Request;
|
||||||
import com.djrapitops.plan.delivery.web.resolver.request.URIQuery;
|
import com.djrapitops.plan.delivery.web.resolver.request.URIQuery;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
|
||||||
@ -38,7 +39,7 @@ public class RequestBodyConverter {
|
|||||||
return new URIQuery(new String(request.getRequestBody(), StandardCharsets.UTF_8));
|
return new URIQuery(new String(request.getRequestBody(), StandardCharsets.UTF_8));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T> T bodyJson(Request request, Gson gson, Class<T> ofType) {
|
public static <T> T bodyJson(@Untrusted Request request, Gson gson, Class<T> ofType) {
|
||||||
return gson.fromJson(new String(request.getRequestBody(), StandardCharsets.UTF_8), ofType);
|
return gson.fromJson(new String(request.getRequestBody(), StandardCharsets.UTF_8), ofType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,10 +36,12 @@ import com.djrapitops.plan.storage.database.DBSystem;
|
|||||||
import com.djrapitops.plan.storage.database.Database;
|
import com.djrapitops.plan.storage.database.Database;
|
||||||
import com.djrapitops.plan.storage.database.queries.containers.ContainerFetchQueries;
|
import com.djrapitops.plan.storage.database.queries.containers.ContainerFetchQueries;
|
||||||
import com.djrapitops.plan.storage.file.PlanFiles;
|
import com.djrapitops.plan.storage.file.PlanFiles;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
import com.djrapitops.plan.utilities.java.Maps;
|
import com.djrapitops.plan.utilities.java.Maps;
|
||||||
import com.djrapitops.plan.utilities.java.UnaryChain;
|
import com.djrapitops.plan.utilities.java.UnaryChain;
|
||||||
import dagger.Lazy;
|
import dagger.Lazy;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.commons.text.StringEscapeUtils;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
@ -375,11 +377,11 @@ public class ResponseFactory {
|
|||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Response ipWhitelist403(String accessor) {
|
public Response ipWhitelist403(@Untrusted String accessor) {
|
||||||
return Response.builder()
|
return Response.builder()
|
||||||
.setMimeType(MimeType.HTML)
|
.setMimeType(MimeType.HTML)
|
||||||
.setContent("<h1>403 Forbidden</h1>" +
|
.setContent("<h1>403 Forbidden</h1>" +
|
||||||
"<p>IP-whitelist enabled, \"" + accessor + "\" is not on the list!</p>")
|
"<p>IP-whitelist enabled, \"" + StringEscapeUtils.escapeHtml4(accessor) + "\" is not on the list!</p>")
|
||||||
.setStatus(403)
|
.setStatus(403)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,7 @@ import com.djrapitops.plan.delivery.webserver.resolver.swagger.SwaggerJsonResolv
|
|||||||
import com.djrapitops.plan.delivery.webserver.resolver.swagger.SwaggerPageResolver;
|
import com.djrapitops.plan.delivery.webserver.resolver.swagger.SwaggerPageResolver;
|
||||||
import com.djrapitops.plan.exceptions.WebUserAuthException;
|
import com.djrapitops.plan.exceptions.WebUserAuthException;
|
||||||
import com.djrapitops.plan.exceptions.connection.ForbiddenException;
|
import com.djrapitops.plan.exceptions.connection.ForbiddenException;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
import com.djrapitops.plan.utilities.logging.ErrorContext;
|
import com.djrapitops.plan.utilities.logging.ErrorContext;
|
||||||
import com.djrapitops.plan.utilities.logging.ErrorLogger;
|
import com.djrapitops.plan.utilities.logging.ErrorLogger;
|
||||||
import dagger.Lazy;
|
import dagger.Lazy;
|
||||||
@ -167,7 +168,7 @@ public class ResponseResolver {
|
|||||||
return request -> Optional.of(response.get());
|
return request -> Optional.of(response.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
public Response getResponse(Request request) {
|
public Response getResponse(@Untrusted Request request) {
|
||||||
try {
|
try {
|
||||||
return tryToGetResponse(request);
|
return tryToGetResponse(request);
|
||||||
} catch (NotFoundException e) {
|
} catch (NotFoundException e) {
|
||||||
@ -189,7 +190,7 @@ public class ResponseResolver {
|
|||||||
* @throws ForbiddenException If the user is not allowed to see the page
|
* @throws ForbiddenException If the user is not allowed to see the page
|
||||||
* @throws BadRequestException If the request did not have required things.
|
* @throws BadRequestException If the request did not have required things.
|
||||||
*/
|
*/
|
||||||
private Response tryToGetResponse(Request request) {
|
private Response tryToGetResponse(@Untrusted Request request) {
|
||||||
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
|
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/OPTIONS
|
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/OPTIONS
|
||||||
return Response.builder().setStatus(204).build();
|
return Response.builder().setStatus(204).build();
|
||||||
|
@ -25,6 +25,7 @@ import com.djrapitops.plan.settings.config.paths.WebserverSettings;
|
|||||||
import com.djrapitops.plan.storage.database.DBSystem;
|
import com.djrapitops.plan.storage.database.DBSystem;
|
||||||
import com.djrapitops.plan.storage.database.queries.objects.WebUserQueries;
|
import com.djrapitops.plan.storage.database.queries.objects.WebUserQueries;
|
||||||
import com.djrapitops.plan.storage.database.transactions.events.CookieChangeTransaction;
|
import com.djrapitops.plan.storage.database.transactions.events.CookieChangeTransaction;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
import net.playeranalytics.plugin.server.PluginLogger;
|
import net.playeranalytics.plugin.server.PluginLogger;
|
||||||
import org.apache.commons.codec.digest.DigestUtils;
|
import org.apache.commons.codec.digest.DigestUtils;
|
||||||
|
|
||||||
@ -70,7 +71,7 @@ public class ActiveCookieStore implements SubSystem {
|
|||||||
Holder.getActiveCookieStore().removeCookie(cookie);
|
Holder.getActiveCookieStore().removeCookie(cookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void removeUserCookie(String username) {
|
public static void removeUserCookie(@Untrusted String username) {
|
||||||
USERS_BY_COOKIE.entrySet().stream().filter(entry -> entry.getValue().getUsername().equals(username))
|
USERS_BY_COOKIE.entrySet().stream().filter(entry -> entry.getValue().getUsername().equals(username))
|
||||||
.findAny()
|
.findAny()
|
||||||
.map(Map.Entry::getKey)
|
.map(Map.Entry::getKey)
|
||||||
@ -106,7 +107,7 @@ public class ActiveCookieStore implements SubSystem {
|
|||||||
USERS_BY_COOKIE.clear();
|
USERS_BY_COOKIE.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Optional<User> checkCookie(String cookie) {
|
public Optional<User> checkCookie(@Untrusted String cookie) {
|
||||||
return Optional.ofNullable(USERS_BY_COOKIE.get(cookie));
|
return Optional.ofNullable(USERS_BY_COOKIE.get(cookie));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,14 +125,14 @@ public class ActiveCookieStore implements SubSystem {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeCookie(String cookie) {
|
public void removeCookie(@Untrusted String cookie) {
|
||||||
checkCookie(cookie).map(User::getUsername)
|
checkCookie(cookie).map(User::getUsername)
|
||||||
.ifPresent(this::deleteCookieByUser);
|
.ifPresent(this::deleteCookieByUser);
|
||||||
USERS_BY_COOKIE.remove(cookie);
|
USERS_BY_COOKIE.remove(cookie);
|
||||||
deleteCookie(cookie);
|
deleteCookie(cookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void deleteCookie(String cookie) {
|
private void deleteCookie(@Untrusted String cookie) {
|
||||||
dbSystem.getDatabase().executeTransaction(CookieChangeTransaction.removeCookie(cookie));
|
dbSystem.getDatabase().executeTransaction(CookieChangeTransaction.removeCookie(cookie));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@ package com.djrapitops.plan.delivery.webserver.auth;
|
|||||||
|
|
||||||
import com.djrapitops.plan.settings.config.PlanConfig;
|
import com.djrapitops.plan.settings.config.PlanConfig;
|
||||||
import com.djrapitops.plan.settings.config.paths.WebserverSettings;
|
import com.djrapitops.plan.settings.config.paths.WebserverSettings;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
@ -44,7 +45,7 @@ public class AllowedIpList {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isAllowed(String accessAddress) {
|
public boolean isAllowed(@Untrusted String accessAddress) {
|
||||||
prepare();
|
prepare();
|
||||||
|
|
||||||
List<String> ips = allowList.get();
|
List<String> ips = allowList.get();
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
package com.djrapitops.plan.delivery.webserver.auth;
|
package com.djrapitops.plan.delivery.webserver.auth;
|
||||||
|
|
||||||
import com.djrapitops.plan.delivery.webserver.http.InternalRequest;
|
import com.djrapitops.plan.delivery.webserver.http.InternalRequest;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
@ -37,8 +38,8 @@ public class AuthenticationExtractor {
|
|||||||
return getCookieAuthentication(internalRequest.getCookies());
|
return getCookieAuthentication(internalRequest.getCookies());
|
||||||
}
|
}
|
||||||
|
|
||||||
private Optional<Authentication> getCookieAuthentication(List<Cookie> cookies) {
|
private Optional<Authentication> getCookieAuthentication(@Untrusted List<Cookie> cookies) {
|
||||||
for (Cookie cookie : cookies) {
|
for (@Untrusted Cookie cookie : cookies) {
|
||||||
if ("auth".equals(cookie.getName())) {
|
if ("auth".equals(cookie.getName())) {
|
||||||
return Optional.of(new CookieAuthentication(activeCookieStore, cookie.getValue()));
|
return Optional.of(new CookieAuthentication(activeCookieStore, cookie.getValue()));
|
||||||
}
|
}
|
||||||
|
@ -16,8 +16,10 @@
|
|||||||
*/
|
*/
|
||||||
package com.djrapitops.plan.delivery.webserver.auth;
|
package com.djrapitops.plan.delivery.webserver.auth;
|
||||||
|
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
@Untrusted
|
||||||
public class Cookie {
|
public class Cookie {
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
|
@ -17,13 +17,15 @@
|
|||||||
package com.djrapitops.plan.delivery.webserver.auth;
|
package com.djrapitops.plan.delivery.webserver.auth;
|
||||||
|
|
||||||
import com.djrapitops.plan.delivery.domain.auth.User;
|
import com.djrapitops.plan.delivery.domain.auth.User;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
|
|
||||||
public class CookieAuthentication implements Authentication {
|
public class CookieAuthentication implements Authentication {
|
||||||
|
|
||||||
private final ActiveCookieStore activeCookieStore;
|
private final ActiveCookieStore activeCookieStore;
|
||||||
|
@Untrusted
|
||||||
private final String cookie;
|
private final String cookie;
|
||||||
|
|
||||||
public CookieAuthentication(ActiveCookieStore activeCookieStore, String cookie) {
|
public CookieAuthentication(ActiveCookieStore activeCookieStore, @Untrusted String cookie) {
|
||||||
this.activeCookieStore = activeCookieStore;
|
this.activeCookieStore = activeCookieStore;
|
||||||
this.cookie = cookie;
|
this.cookie = cookie;
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ package com.djrapitops.plan.delivery.webserver.auth;
|
|||||||
|
|
||||||
import com.djrapitops.plan.delivery.domain.auth.User;
|
import com.djrapitops.plan.delivery.domain.auth.User;
|
||||||
import com.djrapitops.plan.utilities.PassEncryptUtil;
|
import com.djrapitops.plan.utilities.PassEncryptUtil;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
import com.github.benmanes.caffeine.cache.Cache;
|
import com.github.benmanes.caffeine.cache.Cache;
|
||||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||||
import org.apache.commons.codec.digest.DigestUtils;
|
import org.apache.commons.codec.digest.DigestUtils;
|
||||||
@ -42,29 +43,30 @@ public class RegistrationBin {
|
|||||||
// Hide static cache constructor
|
// Hide static cache constructor
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String addInfoForRegistration(String username, String password) {
|
public static String addInfoForRegistration(@Untrusted String username, @Untrusted String password) {
|
||||||
String hash = PassEncryptUtil.createHash(password);
|
String hash = PassEncryptUtil.createHash(password);
|
||||||
String code = DigestUtils.sha256Hex(username + password + System.currentTimeMillis()).substring(0, 12);
|
String code = DigestUtils.sha256Hex(username + password + System.currentTimeMillis()).substring(0, 12);
|
||||||
REGISTRATION_BIN.put(code, new AwaitingForRegistration(username, hash));
|
REGISTRATION_BIN.put(code, new AwaitingForRegistration(username, hash));
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Optional<User> register(String code, UUID linkedToUUID) {
|
public static Optional<User> register(@Untrusted String code, UUID linkedToUUID) {
|
||||||
AwaitingForRegistration found = REGISTRATION_BIN.getIfPresent(code);
|
AwaitingForRegistration found = REGISTRATION_BIN.getIfPresent(code);
|
||||||
if (found == null) return Optional.empty();
|
if (found == null) return Optional.empty();
|
||||||
REGISTRATION_BIN.invalidate(code);
|
REGISTRATION_BIN.invalidate(code);
|
||||||
return Optional.of(found.toUser(linkedToUUID));
|
return Optional.of(found.toUser(linkedToUUID));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean contains(String code) {
|
public static boolean contains(@Untrusted String code) {
|
||||||
return REGISTRATION_BIN.getIfPresent(code) != null;
|
return REGISTRATION_BIN.getIfPresent(code) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class AwaitingForRegistration {
|
private static class AwaitingForRegistration {
|
||||||
|
@Untrusted
|
||||||
private final String username;
|
private final String username;
|
||||||
private final String passwordHash;
|
private final String passwordHash;
|
||||||
|
|
||||||
public AwaitingForRegistration(String username, String passwordHash) {
|
public AwaitingForRegistration(@Untrusted String username, String passwordHash) {
|
||||||
this.username = username;
|
this.username = username;
|
||||||
this.passwordHash = passwordHash;
|
this.passwordHash = passwordHash;
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ import com.djrapitops.plan.delivery.webserver.Addresses;
|
|||||||
import com.djrapitops.plan.settings.config.paths.WebserverSettings;
|
import com.djrapitops.plan.settings.config.paths.WebserverSettings;
|
||||||
import com.djrapitops.plan.settings.locale.Locale;
|
import com.djrapitops.plan.settings.locale.Locale;
|
||||||
import com.djrapitops.plan.settings.locale.lang.PluginLang;
|
import com.djrapitops.plan.settings.locale.lang.PluginLang;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
import com.djrapitops.plan.utilities.logging.ErrorContext;
|
import com.djrapitops.plan.utilities.logging.ErrorContext;
|
||||||
import com.djrapitops.plan.utilities.logging.ErrorLogger;
|
import com.djrapitops.plan.utilities.logging.ErrorLogger;
|
||||||
import net.playeranalytics.plugin.server.PluginLogger;
|
import net.playeranalytics.plugin.server.PluginLogger;
|
||||||
@ -61,7 +62,7 @@ public class WebserverLogMessages {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void warnAboutWhitelistBlock(String accessAddress, String requestedURIString) {
|
public void warnAboutWhitelistBlock(@Untrusted String accessAddress, @Untrusted String requestedURIString) {
|
||||||
logger.info(locale.getString(PluginLang.WEB_SERVER_NOTIFY_IP_WHITELIST_BLOCK, accessAddress, requestedURIString));
|
logger.info(locale.getString(PluginLang.WEB_SERVER_NOTIFY_IP_WHITELIST_BLOCK, accessAddress, requestedURIString));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@ import com.djrapitops.plan.delivery.webserver.configuration.WebserverConfigurati
|
|||||||
import com.djrapitops.plan.exceptions.database.DBOpException;
|
import com.djrapitops.plan.exceptions.database.DBOpException;
|
||||||
import com.djrapitops.plan.storage.database.DBSystem;
|
import com.djrapitops.plan.storage.database.DBSystem;
|
||||||
import com.djrapitops.plan.storage.database.transactions.events.StoreRequestTransaction;
|
import com.djrapitops.plan.storage.database.transactions.events.StoreRequestTransaction;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
import com.djrapitops.plan.utilities.logging.ErrorContext;
|
import com.djrapitops.plan.utilities.logging.ErrorContext;
|
||||||
import com.djrapitops.plan.utilities.logging.ErrorLogger;
|
import com.djrapitops.plan.utilities.logging.ErrorLogger;
|
||||||
import net.playeranalytics.plugin.server.PluginLogger;
|
import net.playeranalytics.plugin.server.PluginLogger;
|
||||||
@ -46,10 +47,10 @@ public class AccessLogger {
|
|||||||
this.errorLogger = errorLogger;
|
this.errorLogger = errorLogger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void log(InternalRequest internalRequest, Request request, Response response) {
|
public void log(@Untrusted InternalRequest internalRequest, @Untrusted Request request, Response response) {
|
||||||
if (webserverConfiguration.logAccessToConsole()) {
|
if (webserverConfiguration.logAccessToConsole()) {
|
||||||
int code = response.getCode();
|
int code = response.getCode();
|
||||||
String message = "Access Log: " + internalRequest.getMethod() + " " +
|
@Untrusted String message = "Access Log: " + internalRequest.getMethod() + " " +
|
||||||
getRequestURI(internalRequest, request) +
|
getRequestURI(internalRequest, request) +
|
||||||
" (from " + internalRequest.getAccessAddress(webserverConfiguration) + ") - " +
|
" (from " + internalRequest.getAccessAddress(webserverConfiguration) + ") - " +
|
||||||
code;
|
code;
|
||||||
@ -82,6 +83,7 @@ public class AccessLogger {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Untrusted
|
||||||
private String getRequestURI(InternalRequest internalRequest, Request request) {
|
private String getRequestURI(InternalRequest internalRequest, Request request) {
|
||||||
return request != null ? request.getPath().asString() + request.getQuery().asString()
|
return request != null ? request.getPath().asString() + request.getQuery().asString()
|
||||||
: internalRequest.getRequestedURIString();
|
: internalRequest.getRequestedURIString();
|
||||||
|
@ -23,6 +23,7 @@ import com.djrapitops.plan.delivery.webserver.auth.Authentication;
|
|||||||
import com.djrapitops.plan.delivery.webserver.auth.AuthenticationExtractor;
|
import com.djrapitops.plan.delivery.webserver.auth.AuthenticationExtractor;
|
||||||
import com.djrapitops.plan.delivery.webserver.auth.Cookie;
|
import com.djrapitops.plan.delivery.webserver.auth.Cookie;
|
||||||
import com.djrapitops.plan.delivery.webserver.configuration.WebserverConfiguration;
|
import com.djrapitops.plan.delivery.webserver.configuration.WebserverConfiguration;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
@ -36,10 +37,11 @@ public interface InternalRequest {
|
|||||||
|
|
||||||
long getTimestamp();
|
long getTimestamp();
|
||||||
|
|
||||||
|
@Untrusted
|
||||||
default String getAccessAddress(WebserverConfiguration webserverConfiguration) {
|
default String getAccessAddress(WebserverConfiguration webserverConfiguration) {
|
||||||
AccessAddressPolicy accessAddressPolicy = webserverConfiguration.getAccessAddressPolicy();
|
AccessAddressPolicy accessAddressPolicy = webserverConfiguration.getAccessAddressPolicy();
|
||||||
if (accessAddressPolicy == AccessAddressPolicy.X_FORWARDED_FOR_HEADER) {
|
if (accessAddressPolicy == AccessAddressPolicy.X_FORWARDED_FOR_HEADER) {
|
||||||
String fromHeader = getAccessAddressFromHeader();
|
@Untrusted String fromHeader = getAccessAddressFromHeader();
|
||||||
if (fromHeader == null) {
|
if (fromHeader == null) {
|
||||||
webserverConfiguration.getWebserverLogMessages().warnAboutXForwardedForSecurityIssue();
|
webserverConfiguration.getWebserverLogMessages().warnAboutXForwardedForSecurityIssue();
|
||||||
return getAccessAddressFromSocketIp();
|
return getAccessAddressFromSocketIp();
|
||||||
|
@ -22,6 +22,7 @@ import com.djrapitops.plan.delivery.web.resolver.request.WebUser;
|
|||||||
import com.djrapitops.plan.delivery.webserver.auth.AuthenticationExtractor;
|
import com.djrapitops.plan.delivery.webserver.auth.AuthenticationExtractor;
|
||||||
import com.djrapitops.plan.delivery.webserver.auth.Cookie;
|
import com.djrapitops.plan.delivery.webserver.auth.Cookie;
|
||||||
import com.djrapitops.plan.delivery.webserver.configuration.WebserverConfiguration;
|
import com.djrapitops.plan.delivery.webserver.configuration.WebserverConfiguration;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import org.apache.commons.text.TextStringBuilder;
|
import org.apache.commons.text.TextStringBuilder;
|
||||||
import org.eclipse.jetty.http.HttpHeader;
|
import org.eclipse.jetty.http.HttpHeader;
|
||||||
@ -72,11 +73,11 @@ public class JettyInternalRequest implements InternalRequest {
|
|||||||
@Override
|
@Override
|
||||||
public com.djrapitops.plan.delivery.web.resolver.request.Request toRequest() {
|
public com.djrapitops.plan.delivery.web.resolver.request.Request toRequest() {
|
||||||
String requestMethod = baseRequest.getMethod();
|
String requestMethod = baseRequest.getMethod();
|
||||||
URIPath path = new URIPath(baseRequest.getHttpURI().getDecodedPath());
|
@Untrusted URIPath path = new URIPath(baseRequest.getHttpURI().getDecodedPath());
|
||||||
URIQuery query = new URIQuery(baseRequest.getHttpURI().getQuery());
|
@Untrusted URIQuery query = new URIQuery(baseRequest.getHttpURI().getQuery());
|
||||||
byte[] requestBody = readRequestBody();
|
@Untrusted byte[] requestBody = readRequestBody();
|
||||||
WebUser user = getWebUser(webserverConfiguration, authenticationExtractor);
|
WebUser user = getWebUser(webserverConfiguration, authenticationExtractor);
|
||||||
Map<String, String> headers = getRequestHeaders();
|
@Untrusted Map<String, String> headers = getRequestHeaders();
|
||||||
return new com.djrapitops.plan.delivery.web.resolver.request.Request(requestMethod, path, query, user, headers, requestBody);
|
return new com.djrapitops.plan.delivery.web.resolver.request.Request(requestMethod, path, query, user, headers, requestBody);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,7 +107,7 @@ public class JettyInternalRequest implements InternalRequest {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Cookie> getCookies() {
|
public List<Cookie> getCookies() {
|
||||||
List<String> textCookies = getCookieHeaders();
|
@Untrusted List<String> textCookies = getCookieHeaders();
|
||||||
List<Cookie> cookies = new ArrayList<>();
|
List<Cookie> cookies = new ArrayList<>();
|
||||||
if (!textCookies.isEmpty()) {
|
if (!textCookies.isEmpty()) {
|
||||||
String[] separated = new TextStringBuilder().appendWithSeparators(textCookies, ";").build().split(";");
|
String[] separated = new TextStringBuilder().appendWithSeparators(textCookies, ";").build().split(";");
|
||||||
|
@ -24,6 +24,7 @@ import com.djrapitops.plan.delivery.webserver.ResponseResolver;
|
|||||||
import com.djrapitops.plan.delivery.webserver.auth.FailReason;
|
import com.djrapitops.plan.delivery.webserver.auth.FailReason;
|
||||||
import com.djrapitops.plan.delivery.webserver.configuration.WebserverConfiguration;
|
import com.djrapitops.plan.delivery.webserver.configuration.WebserverConfiguration;
|
||||||
import com.djrapitops.plan.exceptions.WebUserAuthException;
|
import com.djrapitops.plan.exceptions.WebUserAuthException;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.eclipse.jetty.http.HttpHeader;
|
import org.eclipse.jetty.http.HttpHeader;
|
||||||
|
|
||||||
@ -52,10 +53,10 @@ public class RequestHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Response getResponse(InternalRequest internalRequest) {
|
public Response getResponse(InternalRequest internalRequest) {
|
||||||
String accessAddress = internalRequest.getAccessAddress(webserverConfiguration);
|
@Untrusted String accessAddress = internalRequest.getAccessAddress(webserverConfiguration);
|
||||||
|
|
||||||
Response response;
|
Response response;
|
||||||
Request request = null;
|
@Untrusted Request request = null;
|
||||||
if (bruteForceGuard.shouldPreventRequest(accessAddress)) {
|
if (bruteForceGuard.shouldPreventRequest(accessAddress)) {
|
||||||
response = responseFactory.failedLoginAttempts403();
|
response = responseFactory.failedLoginAttempts403();
|
||||||
} else if (!webserverConfiguration.getAllowedIpList().isAllowed(accessAddress)) {
|
} else if (!webserverConfiguration.getAllowedIpList().isAllowed(accessAddress)) {
|
||||||
@ -81,17 +82,17 @@ public class RequestHandler {
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Response attemptToResolve(Request request, String accessAddress) {
|
private Response attemptToResolve(@Untrusted Request request, @Untrusted String accessAddress) {
|
||||||
Response response = protocolUpgradeResponse(request)
|
Response response = protocolUpgradeResponse(request)
|
||||||
.orElseGet(() -> responseResolver.getResponse(request));
|
.orElseGet(() -> responseResolver.getResponse(request));
|
||||||
request.getUser().ifPresent(user -> processSuccessfulLogin(response.getCode(), accessAddress));
|
request.getUser().ifPresent(user -> processSuccessfulLogin(response.getCode(), accessAddress));
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Optional<Response> protocolUpgradeResponse(Request request) {
|
private Optional<Response> protocolUpgradeResponse(@Untrusted Request request) {
|
||||||
Optional<String> upgrade = request.getHeader(HttpHeader.UPGRADE.asString());
|
@Untrusted Optional<String> upgrade = request.getHeader(HttpHeader.UPGRADE.asString());
|
||||||
if (upgrade.isPresent()) {
|
if (upgrade.isPresent()) {
|
||||||
String value = upgrade.get();
|
@Untrusted String value = upgrade.get();
|
||||||
if ("h2c".equals(value) || "h2".equals(value)) {
|
if ("h2c".equals(value) || "h2".equals(value)) {
|
||||||
return Optional.of(Response.builder()
|
return Optional.of(Response.builder()
|
||||||
.setStatus(101)
|
.setStatus(101)
|
||||||
@ -103,12 +104,12 @@ public class RequestHandler {
|
|||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Response processFailedAuthentication(InternalRequest internalRequest, String accessAddress, WebUserAuthException thrownByAuthentication) {
|
private Response processFailedAuthentication(InternalRequest internalRequest, @Untrusted String accessAddress, WebUserAuthException thrownByAuthentication) {
|
||||||
FailReason failReason = thrownByAuthentication.getFailReason();
|
FailReason failReason = thrownByAuthentication.getFailReason();
|
||||||
if (failReason == FailReason.USER_PASS_MISMATCH) {
|
if (failReason == FailReason.USER_PASS_MISMATCH) {
|
||||||
return processWrongPassword(accessAddress, failReason);
|
return processWrongPassword(accessAddress, failReason);
|
||||||
} else {
|
} else {
|
||||||
String from = internalRequest.getRequestedURIString();
|
@Untrusted String from = internalRequest.getRequestedURIString();
|
||||||
String directTo = StringUtils.startsWithAny(from, "/auth/", "/login") ? "/login" : "/login?from=." + from;
|
String directTo = StringUtils.startsWithAny(from, "/auth/", "/login") ? "/login" : "/login?from=." + from;
|
||||||
return Response.builder()
|
return Response.builder()
|
||||||
.redirectTo(directTo)
|
.redirectTo(directTo)
|
||||||
@ -117,7 +118,7 @@ public class RequestHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Response processWrongPassword(String accessAddress, FailReason failReason) {
|
private Response processWrongPassword(@Untrusted String accessAddress, FailReason failReason) {
|
||||||
bruteForceGuard.increaseAttemptCountOnFailedLogin(accessAddress);
|
bruteForceGuard.increaseAttemptCountOnFailedLogin(accessAddress);
|
||||||
if (bruteForceGuard.shouldPreventRequest(accessAddress)) {
|
if (bruteForceGuard.shouldPreventRequest(accessAddress)) {
|
||||||
return responseFactory.failedLoginAttempts403();
|
return responseFactory.failedLoginAttempts403();
|
||||||
@ -126,7 +127,7 @@ public class RequestHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processSuccessfulLogin(int responseCode, String accessAddress) {
|
private void processSuccessfulLogin(int responseCode, @Untrusted String accessAddress) {
|
||||||
boolean successfulLogin = responseCode != 401;
|
boolean successfulLogin = responseCode != 401;
|
||||||
boolean notForbidden = responseCode != 403;
|
boolean notForbidden = responseCode != 403;
|
||||||
if (successfulLogin && notForbidden) {
|
if (successfulLogin && notForbidden) {
|
||||||
|
@ -26,7 +26,9 @@ import com.djrapitops.plan.delivery.webserver.ResponseFactory;
|
|||||||
import com.djrapitops.plan.identification.UUIDUtility;
|
import com.djrapitops.plan.identification.UUIDUtility;
|
||||||
import com.djrapitops.plan.settings.config.PlanConfig;
|
import com.djrapitops.plan.settings.config.PlanConfig;
|
||||||
import com.djrapitops.plan.settings.config.paths.PluginSettings;
|
import com.djrapitops.plan.settings.config.paths.PluginSettings;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
@ -60,17 +62,22 @@ public class PlayerPageResolver implements Resolver {
|
|||||||
public boolean canAccess(Request request) {
|
public boolean canAccess(Request request) {
|
||||||
URIPath path = request.getPath();
|
URIPath path = request.getPath();
|
||||||
WebUser user = request.getUser().orElse(new WebUser(""));
|
WebUser user = request.getUser().orElse(new WebUser(""));
|
||||||
boolean isOwnPage = path.getPart(1).map(nameOrUUID -> {
|
boolean isOwnPage = isOwnPage(path, user);
|
||||||
|
return user.hasPermission("page.player.other") || user.hasPermission("page.player.self") && isOwnPage;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private Boolean isOwnPage(@Untrusted URIPath path, WebUser user) {
|
||||||
|
return path.getPart(1).map(nameOrUUID -> {
|
||||||
if (user.getName().equalsIgnoreCase(nameOrUUID)) return true; // name matches user
|
if (user.getName().equalsIgnoreCase(nameOrUUID)) return true; // name matches user
|
||||||
return uuidUtility.getNameOf(nameOrUUID).map(user.getName()::equalsIgnoreCase) // uuid matches user
|
return uuidUtility.getNameOf(nameOrUUID).map(user.getName()::equalsIgnoreCase) // uuid matches user
|
||||||
.orElse(false); // uuid or name don't match
|
.orElse(false); // uuid or name don't match
|
||||||
}).orElse(true); // No name or UUID given
|
}).orElse(true); // No name or UUID given
|
||||||
return user.hasPermission("page.player.other") || user.hasPermission("page.player.self") && isOwnPage;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<Response> resolve(Request request) {
|
public Optional<Response> resolve(Request request) {
|
||||||
URIPath path = request.getPath();
|
@Untrusted URIPath path = request.getPath();
|
||||||
if (StringUtils.containsAny(path.asString(), "/vendor/", "/js/", "/css/", "/img/", "/static/")) {
|
if (StringUtils.containsAny(path.asString(), "/vendor/", "/js/", "/css/", "/img/", "/static/")) {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
@ -78,7 +85,7 @@ public class PlayerPageResolver implements Resolver {
|
|||||||
.map(playerName -> getResponse(request.getPath(), playerName));
|
.map(playerName -> getResponse(request.getPath(), playerName));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Response getResponse(URIPath path, String playerName) {
|
private Response getResponse(@Untrusted URIPath path, @Untrusted String playerName) {
|
||||||
UUID playerUUID = uuidUtility.getUUIDOf(playerName);
|
UUID playerUUID = uuidUtility.getUUIDOf(playerName);
|
||||||
if (playerUUID == null) return responseFactory.uuidNotFound404();
|
if (playerUUID == null) return responseFactory.uuidNotFound404();
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@ import dagger.Lazy;
|
|||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolves '/' URL (Address Root).
|
* Resolves '/' URL (Address Root).
|
||||||
@ -72,7 +73,7 @@ public class RootPageResolver implements NoAuthResolver {
|
|||||||
} else if (user.hasPermission("page.players")) {
|
} else if (user.hasPermission("page.players")) {
|
||||||
return responseFactory.redirectResponse("players");
|
return responseFactory.redirectResponse("players");
|
||||||
} else if (user.hasPermission("page.player.self")) {
|
} else if (user.hasPermission("page.player.self")) {
|
||||||
return responseFactory.redirectResponse("player/" + Html.encodeToURL(user.getName()));
|
return responseFactory.redirectResponse("player/" + user.getUUID().map(UUID::toString).orElseGet(user::getName));
|
||||||
} else {
|
} else {
|
||||||
return responseFactory.forbidden403(user.getName() + " has insufficient permissions to be redirected to any page. Needs one of: 'page.server', 'page.players' or 'page.player.self'");
|
return responseFactory.forbidden403(user.getName() + " has insufficient permissions to be redirected to any page. Needs one of: 'page.server', 'page.players' or 'page.player.self'");
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@ import com.djrapitops.plan.identification.ServerInfo;
|
|||||||
import com.djrapitops.plan.identification.ServerUUID;
|
import com.djrapitops.plan.identification.ServerUUID;
|
||||||
import com.djrapitops.plan.storage.database.DBSystem;
|
import com.djrapitops.plan.storage.database.DBSystem;
|
||||||
import com.djrapitops.plan.storage.database.queries.objects.ServerQueries;
|
import com.djrapitops.plan.storage.database.queries.objects.ServerQueries;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
@ -58,7 +59,7 @@ public class ServerPageResolver implements Resolver {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canAccess(Request request) {
|
public boolean canAccess(Request request) {
|
||||||
String firstPart = request.getPath().getPart(0).orElse("");
|
@Untrusted String firstPart = request.getPath().getPart(0).orElse("");
|
||||||
WebUser permissions = request.getUser().orElse(new WebUser(""));
|
WebUser permissions = request.getUser().orElse(new WebUser(""));
|
||||||
boolean forServerPage = "server".equalsIgnoreCase(firstPart) && permissions.hasPermission("page.server");
|
boolean forServerPage = "server".equalsIgnoreCase(firstPart) && permissions.hasPermission("page.server");
|
||||||
boolean forNetworkPage = "network".equalsIgnoreCase(firstPart) && permissions.hasPermission("page.network");
|
boolean forNetworkPage = "network".equalsIgnoreCase(firstPart) && permissions.hasPermission("page.network");
|
||||||
@ -92,7 +93,7 @@ public class ServerPageResolver implements Resolver {
|
|||||||
return Optional.of(responseFactory.serverPageResponse(serverUUID));
|
return Optional.of(responseFactory.serverPageResponse(serverUUID));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Optional<ServerUUID> getServerUUID(URIPath path) {
|
private Optional<ServerUUID> getServerUUID(@Untrusted URIPath path) {
|
||||||
if (serverInfo.getServer().isProxy()
|
if (serverInfo.getServer().isProxy()
|
||||||
&& path.getPart(0).map("network"::equals).orElse(false)
|
&& path.getPart(0).map("network"::equals).orElse(false)
|
||||||
) {
|
) {
|
||||||
|
@ -21,6 +21,7 @@ import com.djrapitops.plan.delivery.web.resolver.Response;
|
|||||||
import com.djrapitops.plan.delivery.web.resolver.request.Request;
|
import com.djrapitops.plan.delivery.web.resolver.request.Request;
|
||||||
import com.djrapitops.plan.delivery.web.resolver.request.URIPath;
|
import com.djrapitops.plan.delivery.web.resolver.request.URIPath;
|
||||||
import com.djrapitops.plan.delivery.webserver.ResponseFactory;
|
import com.djrapitops.plan.delivery.webserver.ResponseFactory;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
@ -51,7 +52,7 @@ public class StaticResourceResolver implements NoAuthResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Response getResponse(Request request) {
|
private Response getResponse(Request request) {
|
||||||
String resource = getPath(request).asString().substring(1);
|
@Untrusted String resource = getPath(request).asString().substring(1);
|
||||||
if (resource.endsWith(".css")) {
|
if (resource.endsWith(".css")) {
|
||||||
return responseFactory.cssResponse(resource);
|
return responseFactory.cssResponse(resource);
|
||||||
}
|
}
|
||||||
@ -68,7 +69,7 @@ public class StaticResourceResolver implements NoAuthResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private URIPath getPath(Request request) {
|
private URIPath getPath(Request request) {
|
||||||
URIPath path = request.getPath();
|
@Untrusted URIPath path = request.getPath();
|
||||||
// Remove everything before /vendor /css /js or /img
|
// Remove everything before /vendor /css /js or /img
|
||||||
while (!path.getPart(0).map(part -> part.matches(PART_REGEX)).orElse(true)) {
|
while (!path.getPart(0).map(part -> part.matches(PART_REGEX)).orElse(true)) {
|
||||||
path = path.omitFirst();
|
path = path.omitFirst();
|
||||||
|
@ -22,6 +22,7 @@ import com.djrapitops.plan.delivery.web.resolver.request.Request;
|
|||||||
import com.djrapitops.plan.delivery.web.resolver.request.WebUser;
|
import com.djrapitops.plan.delivery.web.resolver.request.WebUser;
|
||||||
import com.djrapitops.plan.delivery.webserver.ResponseFactory;
|
import com.djrapitops.plan.delivery.webserver.ResponseFactory;
|
||||||
import com.djrapitops.plan.delivery.webserver.http.WebServer;
|
import com.djrapitops.plan.delivery.webserver.http.WebServer;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
import dagger.Lazy;
|
import dagger.Lazy;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
@ -44,10 +45,10 @@ public class LoginPageResolver implements NoAuthResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<Response> resolve(Request request) {
|
public Optional<Response> resolve(@Untrusted Request request) {
|
||||||
Optional<WebUser> user = request.getUser();
|
Optional<WebUser> user = request.getUser();
|
||||||
if (user.isPresent() || !webServer.get().isAuthRequired()) {
|
if (user.isPresent() || !webServer.get().isAuthRequired()) {
|
||||||
Optional<String> from = request.getQuery().get("from")
|
@Untrusted Optional<String> from = request.getQuery().get("from")
|
||||||
.filter(redirectBackTo -> !redirectBackTo.startsWith("http"));
|
.filter(redirectBackTo -> !redirectBackTo.startsWith("http"));
|
||||||
return Optional.of(responseFactory.redirectResponse(from.orElse("/")));
|
return Optional.of(responseFactory.redirectResponse(from.orElse("/")));
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@ import com.djrapitops.plan.exceptions.WebUserAuthException;
|
|||||||
import com.djrapitops.plan.exceptions.database.DBOpException;
|
import com.djrapitops.plan.exceptions.database.DBOpException;
|
||||||
import com.djrapitops.plan.storage.database.DBSystem;
|
import com.djrapitops.plan.storage.database.DBSystem;
|
||||||
import com.djrapitops.plan.storage.database.queries.objects.WebUserQueries;
|
import com.djrapitops.plan.storage.database.queries.objects.WebUserQueries;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.media.Content;
|
import io.swagger.v3.oas.annotations.media.Content;
|
||||||
import io.swagger.v3.oas.annotations.media.ExampleObject;
|
import io.swagger.v3.oas.annotations.media.ExampleObject;
|
||||||
@ -92,11 +93,11 @@ public class LoginResolver implements NoAuthResolver {
|
|||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public User getUser(Request request) {
|
public User getUser(@Untrusted Request request) {
|
||||||
URIQuery form = RequestBodyConverter.formBody(request);
|
@Untrusted URIQuery form = RequestBodyConverter.formBody(request);
|
||||||
URIQuery query = request.getQuery();
|
@Untrusted URIQuery query = request.getQuery();
|
||||||
String username = getUser(form, query);
|
@Untrusted String username = getUser(form, query);
|
||||||
String password = getPassword(form, query);
|
@Untrusted String password = getPassword(form, query);
|
||||||
User user = dbSystem.getDatabase().query(WebUserQueries.fetchUser(username))
|
User user = dbSystem.getDatabase().query(WebUserQueries.fetchUser(username))
|
||||||
.orElseThrow(() -> new WebUserAuthException(FailReason.USER_PASS_MISMATCH));
|
.orElseThrow(() -> new WebUserAuthException(FailReason.USER_PASS_MISMATCH));
|
||||||
|
|
||||||
@ -107,13 +108,13 @@ public class LoginResolver implements NoAuthResolver {
|
|||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getPassword(URIQuery form, URIQuery query) {
|
private String getPassword(@Untrusted URIQuery form, @Untrusted URIQuery query) {
|
||||||
return form.get("password")
|
return form.get("password")
|
||||||
.orElseGet(() -> query.get("password")
|
.orElseGet(() -> query.get("password")
|
||||||
.orElseThrow(() -> new BadRequestException("'password' parameter not defined")));
|
.orElseThrow(() -> new BadRequestException("'password' parameter not defined")));
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getUser(URIQuery form, URIQuery query) {
|
private String getUser(@Untrusted URIQuery form, @Untrusted URIQuery query) {
|
||||||
return form.get("user")
|
return form.get("user")
|
||||||
.orElseGet(() -> query.get("user")
|
.orElseGet(() -> query.get("user")
|
||||||
.orElseThrow(() -> new BadRequestException("'user' parameter not defined")));
|
.orElseThrow(() -> new BadRequestException("'user' parameter not defined")));
|
||||||
|
@ -22,6 +22,7 @@ import com.djrapitops.plan.delivery.web.resolver.request.Request;
|
|||||||
import com.djrapitops.plan.delivery.webserver.auth.ActiveCookieStore;
|
import com.djrapitops.plan.delivery.webserver.auth.ActiveCookieStore;
|
||||||
import com.djrapitops.plan.delivery.webserver.auth.FailReason;
|
import com.djrapitops.plan.delivery.webserver.auth.FailReason;
|
||||||
import com.djrapitops.plan.exceptions.WebUserAuthException;
|
import com.djrapitops.plan.exceptions.WebUserAuthException;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.media.Content;
|
import io.swagger.v3.oas.annotations.media.Content;
|
||||||
import io.swagger.v3.oas.annotations.media.ExampleObject;
|
import io.swagger.v3.oas.annotations.media.ExampleObject;
|
||||||
@ -57,13 +58,13 @@ public class LogoutResolver implements NoAuthResolver {
|
|||||||
requestBody = @RequestBody(content = @Content(examples = @ExampleObject()))
|
requestBody = @RequestBody(content = @Content(examples = @ExampleObject()))
|
||||||
)
|
)
|
||||||
@Override
|
@Override
|
||||||
public Optional<Response> resolve(Request request) {
|
public Optional<Response> resolve(@Untrusted Request request) {
|
||||||
String cookies = request.getHeader("Cookie").orElse("");
|
@Untrusted String cookies = request.getHeader("Cookie").orElse("");
|
||||||
String foundCookie = null;
|
@Untrusted String foundCookie = null;
|
||||||
for (String cookie : cookies.split(";")) {
|
for (@Untrusted String cookie : cookies.split(";")) {
|
||||||
if (cookie.isEmpty()) continue;
|
if (cookie.isEmpty()) continue;
|
||||||
String[] split = cookie.split("=");
|
@Untrusted String[] split = cookie.split("=");
|
||||||
String name = split[0];
|
@Untrusted String name = split[0];
|
||||||
if ("auth".equals(name) && split.length > 1) {
|
if ("auth".equals(name) && split.length > 1) {
|
||||||
foundCookie = split[1];
|
foundCookie = split[1];
|
||||||
activeCookieStore.removeCookie(foundCookie);
|
activeCookieStore.removeCookie(foundCookie);
|
||||||
|
@ -22,6 +22,7 @@ import com.djrapitops.plan.delivery.web.resolver.request.Request;
|
|||||||
import com.djrapitops.plan.delivery.web.resolver.request.WebUser;
|
import com.djrapitops.plan.delivery.web.resolver.request.WebUser;
|
||||||
import com.djrapitops.plan.delivery.webserver.ResponseFactory;
|
import com.djrapitops.plan.delivery.webserver.ResponseFactory;
|
||||||
import com.djrapitops.plan.delivery.webserver.http.WebServer;
|
import com.djrapitops.plan.delivery.webserver.http.WebServer;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
import dagger.Lazy;
|
import dagger.Lazy;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
@ -44,7 +45,7 @@ public class RegisterPageResolver implements NoAuthResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<Response> resolve(Request request) {
|
public Optional<Response> resolve(@Untrusted Request request) {
|
||||||
Optional<WebUser> user = request.getUser();
|
Optional<WebUser> user = request.getUser();
|
||||||
if (user.isPresent() || !webServer.get().isAuthRequired()) {
|
if (user.isPresent() || !webServer.get().isAuthRequired()) {
|
||||||
return Optional.of(responseFactory.redirectResponse("/"));
|
return Optional.of(responseFactory.redirectResponse("/"));
|
||||||
|
@ -27,6 +27,7 @@ import com.djrapitops.plan.delivery.webserver.auth.RegistrationBin;
|
|||||||
import com.djrapitops.plan.storage.database.DBSystem;
|
import com.djrapitops.plan.storage.database.DBSystem;
|
||||||
import com.djrapitops.plan.storage.database.queries.objects.WebUserQueries;
|
import com.djrapitops.plan.storage.database.queries.objects.WebUserQueries;
|
||||||
import com.djrapitops.plan.utilities.PassEncryptUtil;
|
import com.djrapitops.plan.utilities.PassEncryptUtil;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
import com.djrapitops.plan.utilities.java.Maps;
|
import com.djrapitops.plan.utilities.java.Maps;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.Parameter;
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
@ -79,8 +80,8 @@ public class RegisterResolver implements NoAuthResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Response getResponse(Request request) {
|
public Response getResponse(Request request) {
|
||||||
URIQuery query = request.getQuery();
|
@Untrusted URIQuery query = request.getQuery();
|
||||||
Optional<String> checkCode = query.get("code");
|
@Untrusted Optional<String> checkCode = query.get("code");
|
||||||
if (checkCode.isPresent()) {
|
if (checkCode.isPresent()) {
|
||||||
return Response.builder()
|
return Response.builder()
|
||||||
.setStatus(200)
|
.setStatus(200)
|
||||||
@ -88,13 +89,13 @@ public class RegisterResolver implements NoAuthResolver {
|
|||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
URIQuery form = RequestBodyConverter.formBody(request);
|
@Untrusted URIQuery form = RequestBodyConverter.formBody(request);
|
||||||
String username = getUser(form, query);
|
@Untrusted String username = getUser(form, query);
|
||||||
|
|
||||||
boolean alreadyExists = dbSystem.getDatabase().query(WebUserQueries.fetchUser(username)).isPresent();
|
boolean alreadyExists = dbSystem.getDatabase().query(WebUserQueries.fetchUser(username)).isPresent();
|
||||||
if (alreadyExists) throw new BadRequestException("User already exists!");
|
if (alreadyExists) throw new BadRequestException("User already exists!");
|
||||||
|
|
||||||
String password = getPassword(form, query);
|
@Untrusted String password = getPassword(form, query);
|
||||||
try {
|
try {
|
||||||
String code = RegistrationBin.addInfoForRegistration(username, password);
|
String code = RegistrationBin.addInfoForRegistration(username, password);
|
||||||
return Response.builder()
|
return Response.builder()
|
||||||
@ -109,13 +110,13 @@ public class RegisterResolver implements NoAuthResolver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getPassword(URIQuery form, URIQuery query) {
|
private String getPassword(@Untrusted URIQuery form, @Untrusted URIQuery query) {
|
||||||
return form.get("password")
|
return form.get("password")
|
||||||
.orElseGet(() -> query.get("password")
|
.orElseGet(() -> query.get("password")
|
||||||
.orElseThrow(() -> new BadRequestException("'password' parameter not defined")));
|
.orElseThrow(() -> new BadRequestException("'password' parameter not defined")));
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getUser(URIQuery form, URIQuery query) {
|
private String getUser(@Untrusted URIQuery form, @Untrusted URIQuery query) {
|
||||||
return form.get("user")
|
return form.get("user")
|
||||||
.orElseGet(() -> query.get("user")
|
.orElseGet(() -> query.get("user")
|
||||||
.orElseThrow(() -> new BadRequestException("'user' parameter not defined")));
|
.orElseThrow(() -> new BadRequestException("'user' parameter not defined")));
|
||||||
|
@ -32,6 +32,7 @@ import com.djrapitops.plan.extension.implementation.storage.queries.ExtensionSer
|
|||||||
import com.djrapitops.plan.identification.Identifiers;
|
import com.djrapitops.plan.identification.Identifiers;
|
||||||
import com.djrapitops.plan.identification.ServerUUID;
|
import com.djrapitops.plan.identification.ServerUUID;
|
||||||
import com.djrapitops.plan.storage.database.DBSystem;
|
import com.djrapitops.plan.storage.database.DBSystem;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.Parameter;
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
import io.swagger.v3.oas.annotations.enums.ParameterIn;
|
import io.swagger.v3.oas.annotations.enums.ParameterIn;
|
||||||
@ -88,14 +89,14 @@ public class ExtensionJSONResolver implements Resolver {
|
|||||||
)
|
)
|
||||||
@Override
|
@Override
|
||||||
public Optional<Response> resolve(Request request) {
|
public Optional<Response> resolve(Request request) {
|
||||||
String identifier = request.getQuery().get("server")
|
@Untrusted String identifier = request.getQuery().get("server")
|
||||||
.orElseThrow(() -> new BadRequestException("'server' parameter was not given"));
|
.orElseThrow(() -> new BadRequestException("'server' parameter was not given"));
|
||||||
ServerUUID serverUUID = identifiers.getServerUUID(identifier)
|
ServerUUID serverUUID = identifiers.getServerUUID(identifier)
|
||||||
.orElseThrow(() -> new NotFoundException("Server with identifier '" + identifier + "' was not found in database"));
|
.orElseThrow(() -> new NotFoundException("Server with given server-parameter was not found in database"));
|
||||||
return Optional.of(getResponse(request, serverUUID));
|
return Optional.of(getResponse(request, serverUUID));
|
||||||
}
|
}
|
||||||
|
|
||||||
private JSONStorage.StoredJSON getJSON(Request request, ServerUUID serverUUID) {
|
private JSONStorage.StoredJSON getJSON(@Untrusted Request request, ServerUUID serverUUID) {
|
||||||
Optional<Long> timestamp = Identifiers.getTimestamp(request);
|
Optional<Long> timestamp = Identifiers.getTimestamp(request);
|
||||||
|
|
||||||
return jsonResolverService.resolve(
|
return jsonResolverService.resolve(
|
||||||
|
@ -29,6 +29,7 @@ import com.djrapitops.plan.delivery.webserver.cache.DataID;
|
|||||||
import com.djrapitops.plan.delivery.webserver.cache.JSONStorage;
|
import com.djrapitops.plan.delivery.webserver.cache.JSONStorage;
|
||||||
import com.djrapitops.plan.identification.Identifiers;
|
import com.djrapitops.plan.identification.Identifiers;
|
||||||
import com.djrapitops.plan.identification.ServerUUID;
|
import com.djrapitops.plan.identification.ServerUUID;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.Parameter;
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
import io.swagger.v3.oas.annotations.enums.ParameterIn;
|
import io.swagger.v3.oas.annotations.enums.ParameterIn;
|
||||||
@ -41,7 +42,6 @@ import jakarta.ws.rs.Path;
|
|||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -121,7 +121,7 @@ public class GraphsJSONResolver implements Resolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Response getResponse(Request request) {
|
private Response getResponse(Request request) {
|
||||||
String type = request.getQuery().get("type")
|
@Untrusted String type = request.getQuery().get("type")
|
||||||
.orElseThrow(() -> new BadRequestException("'type' parameter was not defined."));
|
.orElseThrow(() -> new BadRequestException("'type' parameter was not defined."));
|
||||||
|
|
||||||
DataID dataID = getDataID(type);
|
DataID dataID = getDataID(type);
|
||||||
@ -132,7 +132,7 @@ public class GraphsJSONResolver implements Resolver {
|
|||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private JSONStorage.StoredJSON getGraphJSON(Request request, DataID dataID) {
|
private JSONStorage.StoredJSON getGraphJSON(@Untrusted Request request, DataID dataID) {
|
||||||
Optional<Long> timestamp = Identifiers.getTimestamp(request);
|
Optional<Long> timestamp = Identifiers.getTimestamp(request);
|
||||||
|
|
||||||
JSONStorage.StoredJSON storedJSON;
|
JSONStorage.StoredJSON storedJSON;
|
||||||
@ -151,7 +151,7 @@ public class GraphsJSONResolver implements Resolver {
|
|||||||
return storedJSON;
|
return storedJSON;
|
||||||
}
|
}
|
||||||
|
|
||||||
private DataID getDataID(String type) {
|
private DataID getDataID(@Untrusted String type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case "performance":
|
case "performance":
|
||||||
return DataID.GRAPH_PERFORMANCE;
|
return DataID.GRAPH_PERFORMANCE;
|
||||||
@ -186,7 +186,7 @@ public class GraphsJSONResolver implements Resolver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object generateGraphDataJSONOfType(DataID id, ServerUUID serverUUID, URIQuery query) {
|
private Object generateGraphDataJSONOfType(DataID id, ServerUUID serverUUID, @Untrusted URIQuery query) {
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case GRAPH_PERFORMANCE:
|
case GRAPH_PERFORMANCE:
|
||||||
return graphJSON.performanceGraphJSON(serverUUID);
|
return graphJSON.performanceGraphJSON(serverUUID);
|
||||||
@ -218,15 +218,15 @@ public class GraphsJSONResolver implements Resolver {
|
|||||||
query.get("after").map(Long::parseLong).orElse(0L),
|
query.get("after").map(Long::parseLong).orElse(0L),
|
||||||
query.get("before").map(Long::parseLong).orElse(System.currentTimeMillis())
|
query.get("before").map(Long::parseLong).orElse(System.currentTimeMillis())
|
||||||
);
|
);
|
||||||
} catch (NumberFormatException e) {
|
} catch (@Untrusted NumberFormatException e) {
|
||||||
throw new BadRequestException("'after' or 'before' is not a epoch millisecond (number) " + e.getMessage());
|
throw new BadRequestException("'after' or 'before' is not a epoch millisecond (number)");
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return Collections.singletonMap("error", "Undefined ID: " + id.name());
|
throw new BadRequestException("Graph type not supported with server-parameter (" + id.name() + ")");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object generateGraphDataJSONOfType(DataID id, URIQuery query) {
|
private Object generateGraphDataJSONOfType(DataID id, @Untrusted URIQuery query) {
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case GRAPH_ACTIVITY:
|
case GRAPH_ACTIVITY:
|
||||||
return graphJSON.activityGraphsJSONAsMap();
|
return graphJSON.activityGraphsJSONAsMap();
|
||||||
@ -246,11 +246,11 @@ public class GraphsJSONResolver implements Resolver {
|
|||||||
query.get("after").map(Long::parseLong).orElse(0L),
|
query.get("after").map(Long::parseLong).orElse(0L),
|
||||||
query.get("before").map(Long::parseLong).orElse(System.currentTimeMillis())
|
query.get("before").map(Long::parseLong).orElse(System.currentTimeMillis())
|
||||||
);
|
);
|
||||||
} catch (NumberFormatException e) {
|
} catch (@Untrusted NumberFormatException e) {
|
||||||
throw new BadRequestException("'after' or 'before' is not a epoch millisecond (number) " + e.getMessage());
|
throw new BadRequestException("'after' or 'before' is not a epoch millisecond (number)");
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return Collections.singletonMap("error", "Undefined ID: " + id.name());
|
throw new BadRequestException("Graph type not supported without server-parameter (" + id.name() + ")");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -31,6 +31,7 @@ import com.djrapitops.plan.settings.locale.LocaleSystem;
|
|||||||
import com.djrapitops.plan.settings.locale.lang.Lang;
|
import com.djrapitops.plan.settings.locale.lang.Lang;
|
||||||
import com.djrapitops.plan.storage.file.PlanFiles;
|
import com.djrapitops.plan.storage.file.PlanFiles;
|
||||||
import com.djrapitops.plan.storage.file.Resource;
|
import com.djrapitops.plan.storage.file.Resource;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.Parameter;
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
import io.swagger.v3.oas.annotations.enums.ParameterIn;
|
import io.swagger.v3.oas.annotations.enums.ParameterIn;
|
||||||
@ -96,7 +97,7 @@ public class LocaleJSONResolver implements NoAuthResolver {
|
|||||||
private Response getResponse(Request request) {
|
private Response getResponse(Request request) {
|
||||||
ResponseBuilder builder = Response.builder();
|
ResponseBuilder builder = Response.builder();
|
||||||
|
|
||||||
Optional<String> langCode = request.getPath().getPart(1);
|
@Untrusted Optional<String> langCode = request.getPath().getPart(1);
|
||||||
Map<String, Object> json = langCode
|
Map<String, Object> json = langCode
|
||||||
.map(this::getLocaleJSON)
|
.map(this::getLocaleJSON)
|
||||||
.orElseGet(this::getLanguageListJSON);
|
.orElseGet(this::getLanguageListJSON);
|
||||||
@ -137,7 +138,7 @@ public class LocaleJSONResolver implements NoAuthResolver {
|
|||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, Object> getLocaleJSON(String langCode) {
|
private Map<String, Object> getLocaleJSON(@Untrusted String langCode) {
|
||||||
try {
|
try {
|
||||||
LangCode code = LangCode.valueOf(langCode.toUpperCase());
|
LangCode code = LangCode.valueOf(langCode.toUpperCase());
|
||||||
Map<String, Object> json = new TreeMap<>();
|
Map<String, Object> json = new TreeMap<>();
|
||||||
@ -153,7 +154,7 @@ public class LocaleJSONResolver implements NoAuthResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return dfs(loadLocale(file), json);
|
return dfs(loadLocale(file), json);
|
||||||
} catch (IllegalArgumentException noSuchEnum) {
|
} catch (@Untrusted IllegalArgumentException noSuchEnum) {
|
||||||
return Collections.emptyMap();
|
return Collections.emptyMap();
|
||||||
} catch (IOException dfsFileLookupError) {
|
} catch (IOException dfsFileLookupError) {
|
||||||
throw new UncheckedIOException(dfsFileLookupError);
|
throw new UncheckedIOException(dfsFileLookupError);
|
||||||
|
@ -33,6 +33,7 @@ import com.djrapitops.plan.settings.locale.lang.GenericLang;
|
|||||||
import com.djrapitops.plan.storage.database.DBSystem;
|
import com.djrapitops.plan.storage.database.DBSystem;
|
||||||
import com.djrapitops.plan.storage.database.Database;
|
import com.djrapitops.plan.storage.database.Database;
|
||||||
import com.djrapitops.plan.storage.database.queries.objects.TPSQueries;
|
import com.djrapitops.plan.storage.database.queries.objects.TPSQueries;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
@ -119,7 +120,7 @@ public class NetworkPerformanceJSONResolver implements Resolver {
|
|||||||
.build());
|
.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<UUID> getUUIDList(String jsonString) {
|
private List<UUID> getUUIDList(@Untrusted String jsonString) {
|
||||||
return gson.fromJson(jsonString, new TypeToken<List<UUID>>() {}.getType());
|
return gson.fromJson(jsonString, new TypeToken<List<UUID>>() {}.getType());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@ import com.djrapitops.plan.delivery.webserver.cache.DataID;
|
|||||||
import com.djrapitops.plan.delivery.webserver.cache.JSONStorage;
|
import com.djrapitops.plan.delivery.webserver.cache.JSONStorage;
|
||||||
import com.djrapitops.plan.identification.Identifiers;
|
import com.djrapitops.plan.identification.Identifiers;
|
||||||
import com.djrapitops.plan.identification.ServerUUID;
|
import com.djrapitops.plan.identification.ServerUUID;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.Parameter;
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
import io.swagger.v3.oas.annotations.enums.ParameterIn;
|
import io.swagger.v3.oas.annotations.enums.ParameterIn;
|
||||||
@ -100,7 +101,7 @@ public class PlayersTableJSONResolver implements Resolver {
|
|||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private JSONStorage.StoredJSON getStoredJSON(Request request) {
|
private JSONStorage.StoredJSON getStoredJSON(@Untrusted Request request) {
|
||||||
Optional<Long> timestamp = Identifiers.getTimestamp(request);
|
Optional<Long> timestamp = Identifiers.getTimestamp(request);
|
||||||
JSONStorage.StoredJSON storedJSON;
|
JSONStorage.StoredJSON storedJSON;
|
||||||
if (request.getQuery().get("server").isPresent()) {
|
if (request.getQuery().get("server").isPresent()) {
|
||||||
|
@ -47,6 +47,7 @@ import com.djrapitops.plan.storage.database.queries.filter.QueryFilters;
|
|||||||
import com.djrapitops.plan.storage.database.queries.objects.GeoInfoQueries;
|
import com.djrapitops.plan.storage.database.queries.objects.GeoInfoQueries;
|
||||||
import com.djrapitops.plan.storage.database.queries.objects.SessionQueries;
|
import com.djrapitops.plan.storage.database.queries.objects.SessionQueries;
|
||||||
import com.djrapitops.plan.storage.database.queries.objects.playertable.QueryTablePlayersQuery;
|
import com.djrapitops.plan.storage.database.queries.objects.playertable.QueryTablePlayersQuery;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
import com.djrapitops.plan.utilities.java.Maps;
|
import com.djrapitops.plan.utilities.java.Maps;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
@ -131,12 +132,12 @@ public class QueryJSONResolver implements Resolver {
|
|||||||
return Optional.of(getResponse(request));
|
return Optional.of(getResponse(request));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Response getResponse(Request request) {
|
private Response getResponse(@Untrusted Request request) {
|
||||||
Optional<Response> cachedResult = checkForCachedResult(request);
|
Optional<Response> cachedResult = checkForCachedResult(request);
|
||||||
if (cachedResult.isPresent()) return cachedResult.get();
|
if (cachedResult.isPresent()) return cachedResult.get();
|
||||||
|
|
||||||
InputQueryDto inputQuery = parseInputQuery(request);
|
InputQueryDto inputQuery = parseInputQuery(request);
|
||||||
List<InputFilterDto> queries = inputQuery.getFilters();
|
@Untrusted List<InputFilterDto> queries = inputQuery.getFilters();
|
||||||
|
|
||||||
Filter.Result result = filters.apply(queries);
|
Filter.Result result = filters.apply(queries);
|
||||||
List<Filter.ResultPath> resultPath = result.getInverseResultPath();
|
List<Filter.ResultPath> resultPath = result.getInverseResultPath();
|
||||||
@ -145,7 +146,7 @@ public class QueryJSONResolver implements Resolver {
|
|||||||
return buildAndStoreResponse(inputQuery, result, resultPath);
|
return buildAndStoreResponse(inputQuery, result, resultPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
private InputQueryDto parseInputQuery(Request request) {
|
private InputQueryDto parseInputQuery(@Untrusted Request request) {
|
||||||
if (request.getRequestBody().length == 0) {
|
if (request.getRequestBody().length == 0) {
|
||||||
return parseInputQueryFromQueryParams(request);
|
return parseInputQueryFromQueryParams(request);
|
||||||
} else {
|
} else {
|
||||||
@ -153,11 +154,11 @@ public class QueryJSONResolver implements Resolver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private InputQueryDto parseInputQueryFromQueryParams(Request request) {
|
private InputQueryDto parseInputQueryFromQueryParams(@Untrusted Request request) {
|
||||||
String q = request.getQuery().get("q").orElseThrow(() -> new BadRequestException("'q' parameter not set (expecting json array)"));
|
@Untrusted String q = request.getQuery().get("q").orElseThrow(() -> new BadRequestException("'q' parameter not set (expecting json array)"));
|
||||||
try {
|
try {
|
||||||
String query = URLDecoder.decode(q, StandardCharsets.UTF_8);
|
@Untrusted String query = URLDecoder.decode(q, StandardCharsets.UTF_8);
|
||||||
List<InputFilterDto> queryFilters = InputFilterDto.parse(query, gson);
|
@Untrusted List<InputFilterDto> queryFilters = InputFilterDto.parse(query, gson);
|
||||||
ViewDto view = request.getQuery().get("view")
|
ViewDto view = request.getQuery().get("view")
|
||||||
.map(viewJson -> gson.fromJson(viewJson, ViewDto.class))
|
.map(viewJson -> gson.fromJson(viewJson, ViewDto.class))
|
||||||
.orElseThrow(() -> new BadRequestException("'view' parameter not set (expecting json object {afterDate, afterTime, beforeDate, beforeTime})"));
|
.orElseThrow(() -> new BadRequestException("'view' parameter not set (expecting json object {afterDate, afterTime, beforeDate, beforeTime})"));
|
||||||
@ -167,15 +168,16 @@ public class QueryJSONResolver implements Resolver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Optional<Response> checkForCachedResult(Request request) {
|
private Optional<Response> checkForCachedResult(@Untrusted Request request) {
|
||||||
try {
|
try {
|
||||||
return request.getQuery().get("timestamp")
|
return request.getQuery().get("timestamp")
|
||||||
.flatMap(queryTimestamp -> jsonStorage.fetchExactJson("query", Long.parseLong(queryTimestamp)))
|
.map(Long::parseLong)
|
||||||
|
.flatMap(queryTimestamp -> jsonStorage.fetchExactJson("query", queryTimestamp))
|
||||||
.map(results -> Response.builder()
|
.map(results -> Response.builder()
|
||||||
.setMimeType(MimeType.JSON)
|
.setMimeType(MimeType.JSON)
|
||||||
.setJSONContent(results.json)
|
.setJSONContent(results.json)
|
||||||
.build());
|
.build());
|
||||||
} catch (NumberFormatException e) {
|
} catch (@Untrusted NumberFormatException e) {
|
||||||
throw new BadRequestException("Could not parse 'timestamp' into a number. Remove parameter or fix it.");
|
throw new BadRequestException("Could not parse 'timestamp' into a number. Remove parameter or fix it.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -183,10 +185,10 @@ public class QueryJSONResolver implements Resolver {
|
|||||||
private Response buildAndStoreResponse(InputQueryDto input, Filter.Result result, List<Filter.ResultPath> resultPath) {
|
private Response buildAndStoreResponse(InputQueryDto input, Filter.Result result, List<Filter.ResultPath> resultPath) {
|
||||||
try {
|
try {
|
||||||
long timestamp = System.currentTimeMillis();
|
long timestamp = System.currentTimeMillis();
|
||||||
Map<String, Object> json = Maps.builder(String.class, Object.class)
|
@Untrusted Map<String, Object> json = Maps.builder(String.class, Object.class)
|
||||||
.put("path", resultPath)
|
.put("path", resultPath)
|
||||||
.put("view", input.getView())
|
.put("view", input.getView())
|
||||||
.put("filters", input.getFilters())
|
.put("filters", input.getFilters()) // filters json may contain untrusted data
|
||||||
.put("timestamp", timestamp)
|
.put("timestamp", timestamp)
|
||||||
.build();
|
.build();
|
||||||
if (!result.isEmpty()) {
|
if (!result.isEmpty()) {
|
||||||
|
@ -24,6 +24,7 @@ import com.djrapitops.plan.delivery.web.resolver.Response;
|
|||||||
import com.djrapitops.plan.delivery.web.resolver.exception.BadRequestException;
|
import com.djrapitops.plan.delivery.web.resolver.exception.BadRequestException;
|
||||||
import com.djrapitops.plan.delivery.web.resolver.exception.NotFoundException;
|
import com.djrapitops.plan.delivery.web.resolver.exception.NotFoundException;
|
||||||
import com.djrapitops.plan.delivery.web.resolver.request.Request;
|
import com.djrapitops.plan.delivery.web.resolver.request.Request;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.Parameter;
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
import io.swagger.v3.oas.annotations.enums.ParameterIn;
|
import io.swagger.v3.oas.annotations.enums.ParameterIn;
|
||||||
@ -75,7 +76,7 @@ public class ServerIdentityJSONResolver implements Resolver {
|
|||||||
)
|
)
|
||||||
@Override
|
@Override
|
||||||
public Optional<Response> resolve(Request request) {
|
public Optional<Response> resolve(Request request) {
|
||||||
String serverIdentifier = request.getQuery().get("server")
|
@Untrusted String serverIdentifier = request.getQuery().get("server")
|
||||||
.orElseThrow(() -> new BadRequestException("Missing 'server' query parameter"));
|
.orElseThrow(() -> new BadRequestException("Missing 'server' query parameter"));
|
||||||
ServerDto server = jsonFactory.serverForIdentifier(serverIdentifier)
|
ServerDto server = jsonFactory.serverForIdentifier(serverIdentifier)
|
||||||
.orElseThrow(() -> new NotFoundException("Server with identifier '" + serverIdentifier + "' was not found in the database"));
|
.orElseThrow(() -> new NotFoundException("Server with identifier '" + serverIdentifier + "' was not found in the database"));
|
||||||
|
@ -26,6 +26,7 @@ import com.djrapitops.plan.delivery.webserver.cache.AsyncJSONResolverService;
|
|||||||
import com.djrapitops.plan.delivery.webserver.cache.DataID;
|
import com.djrapitops.plan.delivery.webserver.cache.DataID;
|
||||||
import com.djrapitops.plan.identification.Identifiers;
|
import com.djrapitops.plan.identification.Identifiers;
|
||||||
import com.djrapitops.plan.identification.ServerUUID;
|
import com.djrapitops.plan.identification.ServerUUID;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
@ -62,7 +63,7 @@ public class ServerTabJSONResolver<T> implements Resolver {
|
|||||||
return Optional.of(getResponse(request));
|
return Optional.of(getResponse(request));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Response getResponse(Request request) {
|
private Response getResponse(@Untrusted Request request) {
|
||||||
ServerUUID serverUUID = identifiers.getServerUUID(request); // Can throw BadRequestException
|
ServerUUID serverUUID = identifiers.getServerUUID(request); // Can throw BadRequestException
|
||||||
return Response.builder()
|
return Response.builder()
|
||||||
.setMimeType(MimeType.JSON)
|
.setMimeType(MimeType.JSON)
|
||||||
|
@ -27,6 +27,7 @@ import com.djrapitops.plan.delivery.webserver.cache.DataID;
|
|||||||
import com.djrapitops.plan.delivery.webserver.cache.JSONStorage;
|
import com.djrapitops.plan.delivery.webserver.cache.JSONStorage;
|
||||||
import com.djrapitops.plan.identification.Identifiers;
|
import com.djrapitops.plan.identification.Identifiers;
|
||||||
import com.djrapitops.plan.identification.ServerUUID;
|
import com.djrapitops.plan.identification.ServerUUID;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.Parameter;
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
import io.swagger.v3.oas.annotations.enums.ParameterIn;
|
import io.swagger.v3.oas.annotations.enums.ParameterIn;
|
||||||
@ -97,7 +98,7 @@ public class SessionsJSONResolver implements Resolver {
|
|||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private JSONStorage.StoredJSON getStoredJSON(Request request) {
|
private JSONStorage.StoredJSON getStoredJSON(@Untrusted Request request) {
|
||||||
Optional<Long> timestamp = Identifiers.getTimestamp(request);
|
Optional<Long> timestamp = Identifiers.getTimestamp(request);
|
||||||
if (request.getQuery().get("server").isPresent()) {
|
if (request.getQuery().get("server").isPresent()) {
|
||||||
ServerUUID serverUUID = identifiers.getServerUUID(request);
|
ServerUUID serverUUID = identifiers.getServerUUID(request);
|
||||||
|
@ -21,7 +21,7 @@ import com.djrapitops.plan.storage.database.queries.QueryStatement;
|
|||||||
import com.djrapitops.plan.storage.database.sql.tables.ExtensionGroupsTable;
|
import com.djrapitops.plan.storage.database.sql.tables.ExtensionGroupsTable;
|
||||||
import com.djrapitops.plan.storage.database.sql.tables.ExtensionProviderTable;
|
import com.djrapitops.plan.storage.database.sql.tables.ExtensionProviderTable;
|
||||||
import com.djrapitops.plan.storage.database.sql.tables.UsersTable;
|
import com.djrapitops.plan.storage.database.sql.tables.UsersTable;
|
||||||
import org.apache.commons.text.TextStringBuilder;
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
|
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
@ -38,9 +38,10 @@ public class ExtensionUserIdsInGroupQuery extends QueryStatement<Set<Integer>> {
|
|||||||
private final String pluginName;
|
private final String pluginName;
|
||||||
private final String groupProvider;
|
private final String groupProvider;
|
||||||
private final ServerUUID serverUUID;
|
private final ServerUUID serverUUID;
|
||||||
|
@Untrusted
|
||||||
private final List<String> inGroups;
|
private final List<String> inGroups;
|
||||||
|
|
||||||
public ExtensionUserIdsInGroupQuery(String pluginName, String groupProvider, ServerUUID serverUUID, List<String> inGroups) {
|
public ExtensionUserIdsInGroupQuery(String pluginName, String groupProvider, ServerUUID serverUUID, @Untrusted List<String> inGroups) {
|
||||||
super(buildSQL(inGroups), 100);
|
super(buildSQL(inGroups), 100);
|
||||||
this.pluginName = pluginName;
|
this.pluginName = pluginName;
|
||||||
this.groupProvider = groupProvider;
|
this.groupProvider = groupProvider;
|
||||||
@ -48,21 +49,19 @@ public class ExtensionUserIdsInGroupQuery extends QueryStatement<Set<Integer>> {
|
|||||||
this.inGroups = inGroups;
|
this.inGroups = inGroups;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String buildSQL(Collection<String> inGroups) {
|
private static String buildSQL(@Untrusted Collection<String> inGroups) {
|
||||||
TextStringBuilder dynamicInClauseAllocation = new TextStringBuilder();
|
|
||||||
dynamicInClauseAllocation.appendWithSeparators(inGroups.stream().map(group -> "?").toArray(), ",");
|
|
||||||
return SELECT + DISTINCT + "u." + UsersTable.ID +
|
return SELECT + DISTINCT + "u." + UsersTable.ID +
|
||||||
FROM + ExtensionGroupsTable.TABLE_NAME + " groups" +
|
FROM + ExtensionGroupsTable.TABLE_NAME + " groups" +
|
||||||
INNER_JOIN + UsersTable.TABLE_NAME + " u on u." + UsersTable.USER_UUID + "=groups." + ExtensionGroupsTable.USER_UUID +
|
INNER_JOIN + UsersTable.TABLE_NAME + " u on u." + UsersTable.USER_UUID + "=groups." + ExtensionGroupsTable.USER_UUID +
|
||||||
WHERE + ExtensionGroupsTable.PROVIDER_ID + "=" + ExtensionProviderTable.STATEMENT_SELECT_PROVIDER_ID +
|
WHERE + ExtensionGroupsTable.PROVIDER_ID + "=" + ExtensionProviderTable.STATEMENT_SELECT_PROVIDER_ID +
|
||||||
AND + ExtensionGroupsTable.GROUP_NAME + " IN (" + dynamicInClauseAllocation.build() + ")";
|
AND + ExtensionGroupsTable.GROUP_NAME + " IN (" + nParameters(inGroups.size()) + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void prepare(PreparedStatement statement) throws SQLException {
|
public void prepare(PreparedStatement statement) throws SQLException {
|
||||||
ExtensionProviderTable.set3PluginValuesToStatement(statement, 1, groupProvider, pluginName, serverUUID);
|
ExtensionProviderTable.set3PluginValuesToStatement(statement, 1, groupProvider, pluginName, serverUUID);
|
||||||
int index = 4;
|
int index = 4;
|
||||||
for (String group : inGroups) {
|
for (@Untrusted String group : inGroups) {
|
||||||
setStringOrNull(statement, index, group == null || "null".equalsIgnoreCase(group) ? null : group);
|
setStringOrNull(statement, index, group == null || "null".equalsIgnoreCase(group) ? null : group);
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
@ -196,6 +196,7 @@ public class FinishedSession implements DateHolder {
|
|||||||
getExtraData(PlayerKills.class).orElseGet(PlayerKills::new).toJson() + ';' +
|
getExtraData(PlayerKills.class).orElseGet(PlayerKills::new).toJson() + ';' +
|
||||||
getExtraData(MobKillCounter.class).orElseGet(MobKillCounter::new).toJson() + ';' +
|
getExtraData(MobKillCounter.class).orElseGet(MobKillCounter::new).toJson() + ';' +
|
||||||
getExtraData(DeathCounter.class).orElseGet(DeathCounter::new).toJson() + ';' +
|
getExtraData(DeathCounter.class).orElseGet(DeathCounter::new).toJson() + ';' +
|
||||||
|
// Join address contains @Untrusted data
|
||||||
getExtraData(JoinAddress.class).map(JoinAddress::getAddress).orElse(JoinAddressTable.DEFAULT_VALUE_FOR_LOOKUP) + ';' +
|
getExtraData(JoinAddress.class).map(JoinAddress::getAddress).orElse(JoinAddressTable.DEFAULT_VALUE_FOR_LOOKUP) + ';' +
|
||||||
getExtraData(PlayerName.class).map(PlayerName::get).orElseGet(playerUUID::toString);
|
getExtraData(PlayerName.class).map(PlayerName::get).orElseGet(playerUUID::toString);
|
||||||
}
|
}
|
||||||
|
@ -17,11 +17,13 @@
|
|||||||
package com.djrapitops.plan.gathering.domain.event;
|
package com.djrapitops.plan.gathering.domain.event;
|
||||||
|
|
||||||
import com.djrapitops.plan.storage.database.sql.tables.JoinAddressTable;
|
import com.djrapitops.plan.storage.database.sql.tables.JoinAddressTable;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
@Untrusted
|
||||||
public class JoinAddress {
|
public class JoinAddress {
|
||||||
private final Supplier<String> address;
|
private final Supplier<String> address;
|
||||||
|
|
||||||
@ -33,6 +35,7 @@ public class JoinAddress {
|
|||||||
this.address = address;
|
this.address = address;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Untrusted
|
||||||
public String getAddress() {
|
public String getAddress() {
|
||||||
return StringUtils.truncate(address.get(), JoinAddressTable.JOIN_ADDRESS_MAX_LENGTH);
|
return StringUtils.truncate(address.get(), JoinAddressTable.JOIN_ADDRESS_MAX_LENGTH);
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ package com.djrapitops.plan.gathering.importing;
|
|||||||
|
|
||||||
import com.djrapitops.plan.SubSystem;
|
import com.djrapitops.plan.SubSystem;
|
||||||
import com.djrapitops.plan.gathering.importing.importers.Importer;
|
import com.djrapitops.plan.gathering.importing.importers.Importer;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
@ -53,7 +54,7 @@ public class ImportSystem implements SubSystem {
|
|||||||
importers.put(importer.getName(), importer);
|
importers.put(importer.getName(), importer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Optional<Importer> getImporter(String name) {
|
public Optional<Importer> getImporter(@Untrusted String name) {
|
||||||
return Optional.ofNullable(importers.get(name));
|
return Optional.ofNullable(importers.get(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ import com.djrapitops.plan.delivery.web.resolver.request.Request;
|
|||||||
import com.djrapitops.plan.storage.database.DBSystem;
|
import com.djrapitops.plan.storage.database.DBSystem;
|
||||||
import com.djrapitops.plan.storage.database.queries.objects.ServerQueries;
|
import com.djrapitops.plan.storage.database.queries.objects.ServerQueries;
|
||||||
import com.djrapitops.plan.storage.database.queries.objects.UserIdentifierQueries;
|
import com.djrapitops.plan.storage.database.queries.objects.UserIdentifierQueries;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
@ -63,55 +64,7 @@ public class Identifiers {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static Optional<Long> getTimestamp(@Untrusted Request request) {
|
||||||
* Obtain UUID of the server.
|
|
||||||
*
|
|
||||||
* @param identifier Identifier (name or uuid string) of the server
|
|
||||||
* @return UUID of the server.
|
|
||||||
* @throws BadRequestException If the server is not in the database.
|
|
||||||
*/
|
|
||||||
public Optional<ServerUUID> getServerUUID(String identifier) {
|
|
||||||
Optional<ServerUUID> parsed = UUIDUtility.parseFromString(identifier).map(ServerUUID::from);
|
|
||||||
if (parsed.isPresent()) return parsed;
|
|
||||||
return getServerUUIDFromName(identifier);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Optional<ServerUUID> getServerUUIDFromName(String serverName) {
|
|
||||||
return dbSystem.getDatabase().query(ServerQueries.fetchServerMatchingIdentifier(serverName))
|
|
||||||
.map(Server::getUuid);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Obtain UUID of the player.
|
|
||||||
*
|
|
||||||
* @param request for Request, URIQuery needs a 'player' parameter.
|
|
||||||
* @return UUID of the player.
|
|
||||||
* @throws BadRequestException If player parameter is not defined or the player is not in the database.
|
|
||||||
*/
|
|
||||||
public UUID getPlayerUUID(Request request) {
|
|
||||||
String playerIdentifier = request.getQuery().get("player")
|
|
||||||
.orElseThrow(() -> new BadRequestException("'player' parameter was not defined.")).trim();
|
|
||||||
|
|
||||||
Optional<UUID> parsed = UUIDUtility.parseFromString(playerIdentifier);
|
|
||||||
return parsed.orElseGet(() -> getPlayerUUIDFromName(playerIdentifier));
|
|
||||||
}
|
|
||||||
|
|
||||||
private UUID getPlayerUUIDFromName(String playerName) {
|
|
||||||
return dbSystem.getDatabase()
|
|
||||||
.query(UserIdentifierQueries.fetchPlayerUUIDOf(playerName))
|
|
||||||
.orElseThrow(() -> new BadRequestException("Given 'player' was not found in the database."));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public UUID getPlayerUUID(String name) {
|
|
||||||
return uuidUtility.getUUIDOf(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Optional<Integer> getPlayerUserId(UUID playerUUID) {
|
|
||||||
return dbSystem.getDatabase().query(UserIdentifierQueries.fetchUserId(playerUUID));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Optional<Long> getTimestamp(Request request) {
|
|
||||||
try {
|
try {
|
||||||
long currentTime = System.currentTimeMillis();
|
long currentTime = System.currentTimeMillis();
|
||||||
long timestamp = request.getQuery().get("timestamp")
|
long timestamp = request.getQuery().get("timestamp")
|
||||||
@ -125,4 +78,52 @@ public class Identifiers {
|
|||||||
throw new BadRequestException("'timestamp' was not a number: " + nonNumberTimestamp.getMessage());
|
throw new BadRequestException("'timestamp' was not a number: " + nonNumberTimestamp.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain UUID of the server.
|
||||||
|
*
|
||||||
|
* @param identifier Identifier (name or uuid string) of the server
|
||||||
|
* @return UUID of the server.
|
||||||
|
* @throws BadRequestException If the server is not in the database.
|
||||||
|
*/
|
||||||
|
public Optional<ServerUUID> getServerUUID(@Untrusted String identifier) {
|
||||||
|
Optional<ServerUUID> parsed = UUIDUtility.parseFromString(identifier).map(ServerUUID::from);
|
||||||
|
if (parsed.isPresent()) return parsed;
|
||||||
|
return getServerUUIDFromName(identifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Optional<ServerUUID> getServerUUIDFromName(@Untrusted String serverName) {
|
||||||
|
return dbSystem.getDatabase().query(ServerQueries.fetchServerMatchingIdentifier(serverName))
|
||||||
|
.map(Server::getUuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain UUID of the player.
|
||||||
|
*
|
||||||
|
* @param request for Request, URIQuery needs a 'player' parameter.
|
||||||
|
* @return UUID of the player.
|
||||||
|
* @throws BadRequestException If player parameter is not defined or the player is not in the database.
|
||||||
|
*/
|
||||||
|
public UUID getPlayerUUID(@Untrusted Request request) {
|
||||||
|
@Untrusted String playerIdentifier = request.getQuery().get("player")
|
||||||
|
.orElseThrow(() -> new BadRequestException("'player' parameter was not defined.")).trim();
|
||||||
|
|
||||||
|
Optional<UUID> parsed = UUIDUtility.parseFromString(playerIdentifier);
|
||||||
|
return parsed.orElseGet(() -> getPlayerUUIDFromName(playerIdentifier));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public UUID getPlayerUUID(String name) {
|
||||||
|
return uuidUtility.getUUIDOf(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<Integer> getPlayerUserId(UUID playerUUID) {
|
||||||
|
return dbSystem.getDatabase().query(UserIdentifierQueries.fetchUserId(playerUUID));
|
||||||
|
}
|
||||||
|
|
||||||
|
private UUID getPlayerUUIDFromName(@Untrusted String playerName) {
|
||||||
|
return dbSystem.getDatabase()
|
||||||
|
.query(UserIdentifierQueries.fetchPlayerUUIDOf(playerName))
|
||||||
|
.orElseThrow(() -> new BadRequestException("Given 'player' was not found in the database."));
|
||||||
|
}
|
||||||
}
|
}
|
@ -19,6 +19,7 @@ package com.djrapitops.plan.identification;
|
|||||||
import com.djrapitops.plan.exceptions.database.DBOpException;
|
import com.djrapitops.plan.exceptions.database.DBOpException;
|
||||||
import com.djrapitops.plan.storage.database.DBSystem;
|
import com.djrapitops.plan.storage.database.DBSystem;
|
||||||
import com.djrapitops.plan.storage.database.queries.objects.UserIdentifierQueries;
|
import com.djrapitops.plan.storage.database.queries.objects.UserIdentifierQueries;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
import com.djrapitops.plan.utilities.logging.ErrorLogger;
|
import com.djrapitops.plan.utilities.logging.ErrorLogger;
|
||||||
import net.playeranalytics.plugin.player.UUIDFetcher;
|
import net.playeranalytics.plugin.player.UUIDFetcher;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
@ -50,18 +51,18 @@ public class UUIDUtility {
|
|||||||
this.errorLogger = errorLogger;
|
this.errorLogger = errorLogger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Optional<UUID> parseFromString(String uuidString) {
|
public static Optional<UUID> parseFromString(@Untrusted String uuidString) {
|
||||||
try {
|
try {
|
||||||
return Optional.of(UUID.fromString(uuidString));
|
return Optional.of(UUID.fromString(uuidString));
|
||||||
} catch (IllegalArgumentException malformedUUIDException) {
|
} catch (@Untrusted IllegalArgumentException malformedUUIDException) {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Optional<String> getNameOf(String possiblePlayerUUID) {
|
public Optional<String> getNameOf(@Untrusted String possiblePlayerUUID) {
|
||||||
try {
|
try {
|
||||||
return getNameOf(UUID.fromString(possiblePlayerUUID));
|
return getNameOf(UUID.fromString(possiblePlayerUUID));
|
||||||
} catch (IllegalArgumentException notUUID) {
|
} catch (@Untrusted IllegalArgumentException notUUID) {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -78,7 +79,7 @@ public class UUIDUtility {
|
|||||||
* @return UUID of the player
|
* @return UUID of the player
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
public UUID getUUIDOf(String playerName) {
|
public UUID getUUIDOf(@Untrusted String playerName) {
|
||||||
if (playerName == null) throw new IllegalArgumentException("Player name can not be null!");
|
if (playerName == null) throw new IllegalArgumentException("Player name can not be null!");
|
||||||
UUID uuid = getUUIDFromString(playerName);
|
UUID uuid = getUUIDFromString(playerName);
|
||||||
if (uuid != null) return uuid;
|
if (uuid != null) return uuid;
|
||||||
@ -87,23 +88,23 @@ public class UUIDUtility {
|
|||||||
.orElse(getUUIDViaUUIDFetcher(playerName));
|
.orElse(getUUIDViaUUIDFetcher(playerName));
|
||||||
}
|
}
|
||||||
|
|
||||||
private UUID getUUIDFromString(String playerName) {
|
private UUID getUUIDFromString(@Untrusted String playerName) {
|
||||||
try {
|
try {
|
||||||
return UUID.fromString(playerName);
|
return UUID.fromString(playerName);
|
||||||
} catch (IllegalArgumentException ignore) {
|
} catch (@Untrusted IllegalArgumentException ignore) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private UUID getUUIDViaUUIDFetcher(String playerName) {
|
private UUID getUUIDViaUUIDFetcher(@Untrusted String playerName) {
|
||||||
try {
|
try {
|
||||||
return UUIDFetcher.getUUIDOf(playerName);
|
return UUIDFetcher.getUUIDOf(playerName);
|
||||||
} catch (Exception | NoClassDefFoundError ignored) {
|
} catch (@Untrusted Exception | NoClassDefFoundError ignored) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Optional<UUID> getUUIDFromDB(String playerName) {
|
private Optional<UUID> getUUIDFromDB(@Untrusted String playerName) {
|
||||||
try {
|
try {
|
||||||
return dbSystem.getDatabase().query(UserIdentifierQueries.fetchPlayerUUIDOf(playerName));
|
return dbSystem.getDatabase().query(UserIdentifierQueries.fetchPlayerUUIDOf(playerName));
|
||||||
} catch (DBOpException e) {
|
} catch (DBOpException e) {
|
||||||
|
@ -23,6 +23,7 @@ import com.djrapitops.plan.identification.ServerUUID;
|
|||||||
import com.djrapitops.plan.storage.database.DBSystem;
|
import com.djrapitops.plan.storage.database.DBSystem;
|
||||||
import com.djrapitops.plan.storage.database.queries.analysis.PlayerCountQueries;
|
import com.djrapitops.plan.storage.database.queries.analysis.PlayerCountQueries;
|
||||||
import com.djrapitops.plan.storage.database.queries.objects.ServerQueries;
|
import com.djrapitops.plan.storage.database.queries.objects.ServerQueries;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
@ -54,11 +55,11 @@ public class OperatorPlaceholders implements Placeholders {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ServerUUID getServerUUID(Arguments parameters) {
|
private ServerUUID getServerUUID(@Untrusted Arguments parameters) {
|
||||||
return parameters.get(0).flatMap(this::getServerUUIDForServerIdentifier).orElseGet(serverInfo::getServerUUID);
|
return parameters.get(0).flatMap(this::getServerUUIDForServerIdentifier).orElseGet(serverInfo::getServerUUID);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Optional<ServerUUID> getServerUUIDForServerIdentifier(String serverIdentifier) {
|
private Optional<ServerUUID> getServerUUIDForServerIdentifier(@Untrusted String serverIdentifier) {
|
||||||
return dbSystem.getDatabase().query(ServerQueries.fetchServerMatchingIdentifier(serverIdentifier))
|
return dbSystem.getDatabase().query(ServerQueries.fetchServerMatchingIdentifier(serverIdentifier))
|
||||||
.map(Server::getUuid);
|
.map(Server::getUuid);
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ import com.djrapitops.plan.delivery.domain.container.PlayerContainer;
|
|||||||
import com.djrapitops.plan.identification.Identifiers;
|
import com.djrapitops.plan.identification.Identifiers;
|
||||||
import com.djrapitops.plan.storage.database.DBSystem;
|
import com.djrapitops.plan.storage.database.DBSystem;
|
||||||
import com.djrapitops.plan.storage.database.queries.containers.ContainerFetchQueries;
|
import com.djrapitops.plan.storage.database.queries.containers.ContainerFetchQueries;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
@ -107,21 +108,21 @@ public final class PlanPlaceholders {
|
|||||||
* value found but the placeholder is registered,
|
* value found but the placeholder is registered,
|
||||||
* otherwise {@code null}
|
* otherwise {@code null}
|
||||||
*/
|
*/
|
||||||
public String onPlaceholderRequest(UUID uuid, String placeholder, List<String> parameters) {
|
public String onPlaceholderRequest(UUID uuid, @Untrusted String placeholder, @Untrusted List<String> parameters) {
|
||||||
for (Entry<String, Function<String, Serializable>> entry : rawHandlers.entrySet()) {
|
for (Entry<String, Function<String, Serializable>> entry : rawHandlers.entrySet()) {
|
||||||
if (placeholder.startsWith(entry.getKey())) {
|
if (placeholder.startsWith(entry.getKey())) {
|
||||||
return Objects.toString(entry.getValue().apply(placeholder));
|
return Objects.toString(entry.getValue().apply(placeholder));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Arguments arguments = new Arguments(parameters);
|
@Untrusted Arguments arguments = new Arguments(parameters);
|
||||||
|
|
||||||
StaticPlaceholderLoader staticLoader = staticPlaceholders.get(placeholder);
|
StaticPlaceholderLoader staticLoader = staticPlaceholders.get(placeholder);
|
||||||
if (staticLoader != null) {
|
if (staticLoader != null) {
|
||||||
return Objects.toString(staticLoader.apply(arguments));
|
return Objects.toString(staticLoader.apply(arguments));
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<String> givenIdentifier = arguments.get(0);
|
@Untrusted Optional<String> givenIdentifier = arguments.get(0);
|
||||||
Optional<UUID> foundUUID = givenIdentifier
|
Optional<UUID> foundUUID = givenIdentifier
|
||||||
.flatMap(this::getPlayerUUIDForIdentifier);
|
.flatMap(this::getPlayerUUIDForIdentifier);
|
||||||
UUID playerUUID = foundUUID.orElse(uuid);
|
UUID playerUUID = foundUUID.orElse(uuid);
|
||||||
@ -142,7 +143,7 @@ public final class PlanPlaceholders {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Optional<UUID> getPlayerUUIDForIdentifier(String identifier) {
|
private Optional<UUID> getPlayerUUIDForIdentifier(@Untrusted String identifier) {
|
||||||
return Optional.ofNullable(identifiers.getPlayerUUID(identifier));
|
return Optional.ofNullable(identifiers.getPlayerUUID(identifier));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@ import com.djrapitops.plan.storage.database.queries.analysis.PlayerCountQueries;
|
|||||||
import com.djrapitops.plan.storage.database.queries.analysis.TopListQueries;
|
import com.djrapitops.plan.storage.database.queries.analysis.TopListQueries;
|
||||||
import com.djrapitops.plan.storage.database.queries.objects.ServerQueries;
|
import com.djrapitops.plan.storage.database.queries.objects.ServerQueries;
|
||||||
import com.djrapitops.plan.storage.database.queries.objects.TPSQueries;
|
import com.djrapitops.plan.storage.database.queries.objects.TPSQueries;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
@ -201,11 +202,11 @@ public class ServerPlaceHolders implements Placeholders {
|
|||||||
registerDynamicCategoryPlaceholders(placeholders, database);
|
registerDynamicCategoryPlaceholders(placeholders, database);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ServerUUID getServerUUID(Arguments parameters) {
|
private ServerUUID getServerUUID(@Untrusted Arguments parameters) {
|
||||||
return parameters.get(0).flatMap(this::getServerUUIDForServerIdentifier).orElseGet(serverInfo::getServerUUID);
|
return parameters.get(0).flatMap(this::getServerUUIDForServerIdentifier).orElseGet(serverInfo::getServerUUID);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Optional<ServerUUID> getServerUUIDForServerIdentifier(String serverIdentifier) {
|
private Optional<ServerUUID> getServerUUIDForServerIdentifier(@Untrusted String serverIdentifier) {
|
||||||
return dbSystem.getDatabase().query(ServerQueries.fetchServerMatchingIdentifier(serverIdentifier))
|
return dbSystem.getDatabase().query(ServerQueries.fetchServerMatchingIdentifier(serverIdentifier))
|
||||||
.map(Server::getUuid);
|
.map(Server::getUuid);
|
||||||
}
|
}
|
||||||
@ -242,7 +243,7 @@ public class ServerPlaceHolders implements Placeholders {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface QueryCreator<T> {
|
interface QueryCreator<T> {
|
||||||
Query<Optional<TopListQueries.TopListEntry<T>>> apply(Integer number, Long timespan, Arguments parameters);
|
Query<Optional<TopListQueries.TopListEntry<T>>> apply(Integer number, Long timespan, @Untrusted Arguments parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class TopCategoryQuery<T> {
|
public static class TopCategoryQuery<T> {
|
||||||
@ -266,7 +267,7 @@ public class ServerPlaceHolders implements Placeholders {
|
|||||||
return timeSpan;
|
return timeSpan;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Query<Optional<TopListQueries.TopListEntry<T>>> getQuery(int i, Arguments parameters) {
|
public Query<Optional<TopListQueries.TopListEntry<T>>> getQuery(int i, @Untrusted Arguments parameters) {
|
||||||
return queryCreator.apply(i, timeSpanMillis, parameters);
|
return queryCreator.apply(i, timeSpanMillis, parameters);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ import com.djrapitops.plan.storage.database.DBSystem;
|
|||||||
import com.djrapitops.plan.storage.database.Database;
|
import com.djrapitops.plan.storage.database.Database;
|
||||||
import com.djrapitops.plan.storage.database.queries.analysis.PlayerCountQueries;
|
import com.djrapitops.plan.storage.database.queries.analysis.PlayerCountQueries;
|
||||||
import com.djrapitops.plan.storage.database.queries.objects.*;
|
import com.djrapitops.plan.storage.database.queries.objects.*;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
@ -219,13 +220,13 @@ public class SessionPlaceHolders implements Placeholders {
|
|||||||
parameters -> database.query(TPSQueries.fetchPeakPlayerCount(getServerUUID(parameters), now() - TimeUnit.DAYS.toMillis(2L))).map(year).orElse("-"));
|
parameters -> database.query(TPSQueries.fetchPeakPlayerCount(getServerUUID(parameters), now() - TimeUnit.DAYS.toMillis(2L))).map(year).orElse("-"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private ServerUUID getServerUUID(Arguments parameters) {
|
private ServerUUID getServerUUID(@Untrusted Arguments parameters) {
|
||||||
return parameters.get(0)
|
return parameters.get(0)
|
||||||
.flatMap(this::getServerUUIDForServerIdentifier)
|
.flatMap(this::getServerUUIDForServerIdentifier)
|
||||||
.orElseGet(serverInfo::getServerUUID);
|
.orElseGet(serverInfo::getServerUUID);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Optional<ServerUUID> getServerUUIDForServerIdentifier(String serverIdentifier) {
|
private Optional<ServerUUID> getServerUUIDForServerIdentifier(@Untrusted String serverIdentifier) {
|
||||||
return dbSystem.getDatabase().query(ServerQueries.fetchServerMatchingIdentifier(serverIdentifier))
|
return dbSystem.getDatabase().query(ServerQueries.fetchServerMatchingIdentifier(serverIdentifier))
|
||||||
.map(Server::getUuid);
|
.map(Server::getUuid);
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
package com.djrapitops.plan.storage.database;
|
package com.djrapitops.plan.storage.database;
|
||||||
|
|
||||||
import com.djrapitops.plan.storage.database.sql.building.Sql;
|
import com.djrapitops.plan.storage.database.sql.building.Sql;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -80,7 +81,7 @@ public enum DBType {
|
|||||||
* @param name the name of the {@code DBType}
|
* @param name the name of the {@code DBType}
|
||||||
* @return an {@code Optional<DBType>}
|
* @return an {@code Optional<DBType>}
|
||||||
*/
|
*/
|
||||||
public static Optional<DBType> getForName(String name) {
|
public static Optional<DBType> getForName(@Untrusted String name) {
|
||||||
for (DBType dbType : DBType.values()) {
|
for (DBType dbType : DBType.values()) {
|
||||||
if (dbType.getName().equalsIgnoreCase(name)) {
|
if (dbType.getName().equalsIgnoreCase(name)) {
|
||||||
return Optional.of(dbType);
|
return Optional.of(dbType);
|
||||||
|
@ -24,7 +24,7 @@ import com.djrapitops.plan.storage.database.sql.tables.ServerTable;
|
|||||||
import com.djrapitops.plan.storage.database.sql.tables.SessionsTable;
|
import com.djrapitops.plan.storage.database.sql.tables.SessionsTable;
|
||||||
import com.djrapitops.plan.storage.database.sql.tables.UserInfoTable;
|
import com.djrapitops.plan.storage.database.sql.tables.UserInfoTable;
|
||||||
import com.djrapitops.plan.storage.database.sql.tables.UsersTable;
|
import com.djrapitops.plan.storage.database.sql.tables.UsersTable;
|
||||||
import com.djrapitops.plan.utilities.Benchmark;
|
import com.djrapitops.plan.utilities.dev.Benchmark;
|
||||||
|
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
package com.djrapitops.plan.storage.database.queries.filter;
|
package com.djrapitops.plan.storage.database.queries.filter;
|
||||||
|
|
||||||
import com.djrapitops.plan.delivery.domain.datatransfer.InputFilterDto;
|
import com.djrapitops.plan.delivery.domain.datatransfer.InputFilterDto;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@ -42,9 +43,9 @@ public interface Filter {
|
|||||||
* @return Set of UUIDs this filter applies to
|
* @return Set of UUIDs this filter applies to
|
||||||
* @throws IllegalArgumentException If the arguments are not valid.
|
* @throws IllegalArgumentException If the arguments are not valid.
|
||||||
*/
|
*/
|
||||||
Set<Integer> getMatchingUserIds(InputFilterDto query);
|
Set<Integer> getMatchingUserIds(@Untrusted InputFilterDto query);
|
||||||
|
|
||||||
default Result apply(InputFilterDto query) {
|
default Result apply(@Untrusted InputFilterDto query) {
|
||||||
try {
|
try {
|
||||||
return new Result(null, getKind(), getMatchingUserIds(query));
|
return new Result(null, getKind(), getMatchingUserIds(query));
|
||||||
} catch (CompleteSetException allMatch) {
|
} catch (CompleteSetException allMatch) {
|
||||||
|
@ -21,6 +21,7 @@ import com.djrapitops.plan.delivery.web.resolver.exception.BadRequestException;
|
|||||||
import com.djrapitops.plan.storage.database.DBSystem;
|
import com.djrapitops.plan.storage.database.DBSystem;
|
||||||
import com.djrapitops.plan.storage.database.queries.filter.filters.AllPlayersFilter;
|
import com.djrapitops.plan.storage.database.queries.filter.filters.AllPlayersFilter;
|
||||||
import com.djrapitops.plan.storage.database.queries.filter.filters.PluginGroupsFilter;
|
import com.djrapitops.plan.storage.database.queries.filter.filters.PluginGroupsFilter;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
@ -70,7 +71,7 @@ public class QueryFilters {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Optional<Filter> getFilter(String kind) {
|
public Optional<Filter> getFilter(@Untrusted String kind) {
|
||||||
prepareFilters();
|
prepareFilters();
|
||||||
return Optional.ofNullable(filters.get(kind));
|
return Optional.ofNullable(filters.get(kind));
|
||||||
}
|
}
|
||||||
@ -82,25 +83,25 @@ public class QueryFilters {
|
|||||||
* @return the result object or null if none of the filterQueries could be applied.
|
* @return the result object or null if none of the filterQueries could be applied.
|
||||||
* @throws BadRequestException If the request kind is not supported or if filter was given bad options.
|
* @throws BadRequestException If the request kind is not supported or if filter was given bad options.
|
||||||
*/
|
*/
|
||||||
public Filter.Result apply(List<InputFilterDto> filterQueries) {
|
public Filter.Result apply(@Untrusted List<InputFilterDto> filterQueries) {
|
||||||
prepareFilters();
|
prepareFilters();
|
||||||
Filter.Result current = null;
|
Filter.Result current = null;
|
||||||
if (filterQueries.isEmpty()) return allPlayersFilter.apply(null);
|
if (filterQueries.isEmpty()) return allPlayersFilter.apply(null);
|
||||||
for (InputFilterDto inputFilterDto : filterQueries) {
|
for (@Untrusted InputFilterDto inputFilterDto : filterQueries) {
|
||||||
current = apply(current, inputFilterDto);
|
current = apply(current, inputFilterDto);
|
||||||
if (current != null && current.isEmpty()) break;
|
if (current != null && current.isEmpty()) break;
|
||||||
}
|
}
|
||||||
return current;
|
return current;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Filter.Result apply(Filter.Result current, InputFilterDto inputFilterDto) {
|
private Filter.Result apply(Filter.Result current, @Untrusted InputFilterDto inputFilterDto) {
|
||||||
String kind = inputFilterDto.getKind();
|
@Untrusted String kind = inputFilterDto.getKind();
|
||||||
Filter filter = getFilter(kind).orElseThrow(() -> new BadRequestException("Filter kind not supported: '" + kind + "'"));
|
Filter filter = getFilter(kind).orElseThrow(() -> new BadRequestException("Filter kind not supported: '" + kind + "'"));
|
||||||
|
|
||||||
return getResult(current, filter, inputFilterDto);
|
return getResult(current, filter, inputFilterDto);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Filter.Result getResult(Filter.Result current, Filter filter, InputFilterDto query) {
|
private Filter.Result getResult(Filter.Result current, Filter filter, @Untrusted InputFilterDto query) {
|
||||||
try {
|
try {
|
||||||
return current == null ? filter.apply(query) : current.apply(filter, query);
|
return current == null ? filter.apply(query) : current.apply(filter, query);
|
||||||
} catch (IllegalArgumentException badOptions) {
|
} catch (IllegalArgumentException badOptions) {
|
||||||
|
@ -24,6 +24,7 @@ import com.djrapitops.plan.settings.locale.Locale;
|
|||||||
import com.djrapitops.plan.storage.database.DBSystem;
|
import com.djrapitops.plan.storage.database.DBSystem;
|
||||||
import com.djrapitops.plan.storage.database.queries.analysis.NetworkActivityIndexQueries;
|
import com.djrapitops.plan.storage.database.queries.analysis.NetworkActivityIndexQueries;
|
||||||
import com.djrapitops.plan.storage.database.queries.filter.CompleteSetException;
|
import com.djrapitops.plan.storage.database.queries.filter.CompleteSetException;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
@ -66,8 +67,8 @@ public class ActivityIndexFilter extends MultiOptionFilter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Integer> getMatchingUserIds(InputFilterDto query) {
|
public Set<Integer> getMatchingUserIds(@Untrusted InputFilterDto query) {
|
||||||
List<String> selected = getSelected(query);
|
@Untrusted List<String> selected = getSelected(query);
|
||||||
String[] options = getOptionsArray();
|
String[] options = getOptionsArray();
|
||||||
|
|
||||||
boolean includeVeryActive = selected.contains(options[0]);
|
boolean includeVeryActive = selected.contains(options[0]);
|
||||||
|
@ -20,6 +20,7 @@ import com.djrapitops.plan.delivery.domain.datatransfer.InputFilterDto;
|
|||||||
import com.djrapitops.plan.storage.database.DBSystem;
|
import com.djrapitops.plan.storage.database.DBSystem;
|
||||||
import com.djrapitops.plan.storage.database.queries.filter.Filter;
|
import com.djrapitops.plan.storage.database.queries.filter.Filter;
|
||||||
import com.djrapitops.plan.storage.database.queries.objects.UserIdentifierQueries;
|
import com.djrapitops.plan.storage.database.queries.objects.UserIdentifierQueries;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
@ -51,7 +52,7 @@ public class AllPlayersFilter implements Filter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Integer> getMatchingUserIds(InputFilterDto query) {
|
public Set<Integer> getMatchingUserIds(@Untrusted InputFilterDto query) {
|
||||||
return dbSystem.getDatabase().query(UserIdentifierQueries.fetchAllUserIds());
|
return dbSystem.getDatabase().query(UserIdentifierQueries.fetchAllUserIds());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ import com.djrapitops.plan.settings.locale.lang.FilterLang;
|
|||||||
import com.djrapitops.plan.storage.database.DBSystem;
|
import com.djrapitops.plan.storage.database.DBSystem;
|
||||||
import com.djrapitops.plan.storage.database.queries.filter.CompleteSetException;
|
import com.djrapitops.plan.storage.database.queries.filter.CompleteSetException;
|
||||||
import com.djrapitops.plan.storage.database.queries.objects.UserInfoQueries;
|
import com.djrapitops.plan.storage.database.queries.objects.UserInfoQueries;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
@ -57,8 +58,8 @@ public class BannedFilter extends MultiOptionFilter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Integer> getMatchingUserIds(InputFilterDto query) {
|
public Set<Integer> getMatchingUserIds(@Untrusted InputFilterDto query) {
|
||||||
List<String> selected = getSelected(query);
|
@Untrusted List<String> selected = getSelected(query);
|
||||||
Set<Integer> userIds = new HashSet<>();
|
Set<Integer> userIds = new HashSet<>();
|
||||||
String[] options = getOptionsArray();
|
String[] options = getOptionsArray();
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ import com.djrapitops.plan.delivery.web.resolver.exception.BadRequestException;
|
|||||||
import com.djrapitops.plan.storage.database.DBSystem;
|
import com.djrapitops.plan.storage.database.DBSystem;
|
||||||
import com.djrapitops.plan.storage.database.queries.filter.Filter;
|
import com.djrapitops.plan.storage.database.queries.filter.Filter;
|
||||||
import com.djrapitops.plan.storage.database.queries.objects.BaseUserQueries;
|
import com.djrapitops.plan.storage.database.queries.objects.BaseUserQueries;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
import com.djrapitops.plan.utilities.java.Maps;
|
import com.djrapitops.plan.utilities.java.Maps;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
@ -61,17 +62,17 @@ public abstract class DateRangeFilter implements Filter {
|
|||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected long getAfter(InputFilterDto query) {
|
protected long getAfter(@Untrusted InputFilterDto query) {
|
||||||
return getTime(query, "afterDate", "afterTime");
|
return getTime(query, "afterDate", "afterTime");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected long getBefore(InputFilterDto query) {
|
protected long getBefore(@Untrusted InputFilterDto query) {
|
||||||
return getTime(query, "beforeDate", "beforeTime");
|
return getTime(query, "beforeDate", "beforeTime");
|
||||||
}
|
}
|
||||||
|
|
||||||
private long getTime(InputFilterDto query, String dateKey, String timeKey) {
|
private long getTime(@Untrusted InputFilterDto query, String dateKey, String timeKey) {
|
||||||
String date = query.get(dateKey).orElseThrow(() -> new BadRequestException("'" + dateKey + "' not specified in parameters for " + getKind()));
|
@Untrusted String date = query.get(dateKey).orElseThrow(() -> new BadRequestException("'" + dateKey + "' not specified in parameters for " + getKind()));
|
||||||
String time = query.get(timeKey).orElseThrow(() -> new BadRequestException("'" + timeKey + "' not specified in parameters for " + getKind()));
|
@Untrusted String time = query.get(timeKey).orElseThrow(() -> new BadRequestException("'" + timeKey + "' not specified in parameters for " + getKind()));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return dateFormat.parse(date + ' ' + time).getTime();
|
return dateFormat.parse(date + ' ' + time).getTime();
|
||||||
|
@ -19,6 +19,7 @@ package com.djrapitops.plan.storage.database.queries.filter.filters;
|
|||||||
import com.djrapitops.plan.delivery.domain.datatransfer.InputFilterDto;
|
import com.djrapitops.plan.delivery.domain.datatransfer.InputFilterDto;
|
||||||
import com.djrapitops.plan.storage.database.DBSystem;
|
import com.djrapitops.plan.storage.database.DBSystem;
|
||||||
import com.djrapitops.plan.storage.database.queries.objects.GeoInfoQueries;
|
import com.djrapitops.plan.storage.database.queries.objects.GeoInfoQueries;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
@ -50,7 +51,7 @@ public class GeolocationsFilter extends MultiOptionFilter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Integer> getMatchingUserIds(InputFilterDto query) {
|
public Set<Integer> getMatchingUserIds(@Untrusted InputFilterDto query) {
|
||||||
return dbSystem.getDatabase().query(GeoInfoQueries.userIdsOfPlayersWithGeolocations(getSelected(query)));
|
return dbSystem.getDatabase().query(GeoInfoQueries.userIdsOfPlayersWithGeolocations(getSelected(query)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ package com.djrapitops.plan.storage.database.queries.filter.filters;
|
|||||||
import com.djrapitops.plan.delivery.domain.datatransfer.InputFilterDto;
|
import com.djrapitops.plan.delivery.domain.datatransfer.InputFilterDto;
|
||||||
import com.djrapitops.plan.storage.database.DBSystem;
|
import com.djrapitops.plan.storage.database.DBSystem;
|
||||||
import com.djrapitops.plan.storage.database.queries.objects.JoinAddressQueries;
|
import com.djrapitops.plan.storage.database.queries.objects.JoinAddressQueries;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
@ -50,7 +51,7 @@ public class JoinAddressFilter extends MultiOptionFilter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Integer> getMatchingUserIds(InputFilterDto query) {
|
public Set<Integer> getMatchingUserIds(@Untrusted InputFilterDto query) {
|
||||||
return dbSystem.getDatabase().query(JoinAddressQueries.userIdsOfPlayersWithJoinAddresses(getSelected(query)));
|
return dbSystem.getDatabase().query(JoinAddressQueries.userIdsOfPlayersWithJoinAddresses(getSelected(query)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ package com.djrapitops.plan.storage.database.queries.filter.filters;
|
|||||||
import com.djrapitops.plan.delivery.domain.datatransfer.InputFilterDto;
|
import com.djrapitops.plan.delivery.domain.datatransfer.InputFilterDto;
|
||||||
import com.djrapitops.plan.storage.database.queries.filter.CompleteSetException;
|
import com.djrapitops.plan.storage.database.queries.filter.CompleteSetException;
|
||||||
import com.djrapitops.plan.storage.database.queries.filter.Filter;
|
import com.djrapitops.plan.storage.database.queries.filter.Filter;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
|
||||||
@ -31,9 +32,9 @@ public abstract class MultiOptionFilter implements Filter {
|
|||||||
return new String[]{"selected"};
|
return new String[]{"selected"};
|
||||||
}
|
}
|
||||||
|
|
||||||
protected List<String> getSelected(InputFilterDto query) {
|
protected List<String> getSelected(@Untrusted InputFilterDto query) {
|
||||||
String selectedJSON = query.get("selected").orElseThrow(IllegalArgumentException::new);
|
@Untrusted String selectedJSON = query.get("selected").orElseThrow(IllegalArgumentException::new);
|
||||||
List<String> selected = new Gson().fromJson(selectedJSON, new TypeToken<List<String>>() {}.getType());
|
@Untrusted List<String> selected = new Gson().fromJson(selectedJSON, new TypeToken<List<String>>() {}.getType());
|
||||||
if (selected.isEmpty()) throw new CompleteSetException();
|
if (selected.isEmpty()) throw new CompleteSetException();
|
||||||
return selected;
|
return selected;
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ import com.djrapitops.plan.settings.locale.lang.FilterLang;
|
|||||||
import com.djrapitops.plan.storage.database.DBSystem;
|
import com.djrapitops.plan.storage.database.DBSystem;
|
||||||
import com.djrapitops.plan.storage.database.queries.filter.CompleteSetException;
|
import com.djrapitops.plan.storage.database.queries.filter.CompleteSetException;
|
||||||
import com.djrapitops.plan.storage.database.queries.objects.UserInfoQueries;
|
import com.djrapitops.plan.storage.database.queries.objects.UserInfoQueries;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
@ -57,8 +58,8 @@ public class OperatorsFilter extends MultiOptionFilter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Integer> getMatchingUserIds(InputFilterDto query) {
|
public Set<Integer> getMatchingUserIds(@Untrusted InputFilterDto query) {
|
||||||
List<String> selected = getSelected(query);
|
@Untrusted List<String> selected = getSelected(query);
|
||||||
Set<Integer> userIds = new HashSet<>();
|
Set<Integer> userIds = new HashSet<>();
|
||||||
String[] options = getOptionsArray();
|
String[] options = getOptionsArray();
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ import com.djrapitops.plan.identification.ServerUUID;
|
|||||||
import com.djrapitops.plan.storage.database.DBSystem;
|
import com.djrapitops.plan.storage.database.DBSystem;
|
||||||
import com.djrapitops.plan.storage.database.queries.objects.ServerQueries;
|
import com.djrapitops.plan.storage.database.queries.objects.ServerQueries;
|
||||||
import com.djrapitops.plan.storage.database.queries.objects.SessionQueries;
|
import com.djrapitops.plan.storage.database.queries.objects.SessionQueries;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
@ -47,10 +48,10 @@ public class PlayedBetweenDateRangeFilter extends DateRangeFilter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Integer> getMatchingUserIds(InputFilterDto query) {
|
public Set<Integer> getMatchingUserIds(@Untrusted InputFilterDto query) {
|
||||||
long after = getAfter(query);
|
long after = getAfter(query);
|
||||||
long before = getBefore(query);
|
long before = getBefore(query);
|
||||||
List<String> serverNames = getServerNames(query);
|
@Untrusted List<String> serverNames = getServerNames(query);
|
||||||
List<ServerUUID> serverUUIDs = serverNames.isEmpty() ? Collections.emptyList() : dbSystem.getDatabase().query(ServerQueries.fetchServersMatchingIdentifiers(serverNames));
|
List<ServerUUID> serverUUIDs = serverNames.isEmpty() ? Collections.emptyList() : dbSystem.getDatabase().query(ServerQueries.fetchServersMatchingIdentifiers(serverNames));
|
||||||
return dbSystem.getDatabase().query(SessionQueries.userIdsOfPlayedBetween(after, before, serverUUIDs));
|
return dbSystem.getDatabase().query(SessionQueries.userIdsOfPlayedBetween(after, before, serverUUIDs));
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ import com.djrapitops.plan.identification.ServerUUID;
|
|||||||
import com.djrapitops.plan.storage.database.DBSystem;
|
import com.djrapitops.plan.storage.database.DBSystem;
|
||||||
import com.djrapitops.plan.storage.database.queries.objects.ServerQueries;
|
import com.djrapitops.plan.storage.database.queries.objects.ServerQueries;
|
||||||
import com.djrapitops.plan.storage.database.queries.objects.UserInfoQueries;
|
import com.djrapitops.plan.storage.database.queries.objects.UserInfoQueries;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
@ -54,8 +55,8 @@ public class PlayedOnServerFilter extends MultiOptionFilter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Integer> getMatchingUserIds(InputFilterDto query) {
|
public Set<Integer> getMatchingUserIds(@Untrusted InputFilterDto query) {
|
||||||
List<String> serverNames = getSelected(query);
|
@Untrusted List<String> serverNames = getSelected(query);
|
||||||
List<ServerUUID> serverUUIDs = serverNames.isEmpty() ? Collections.emptyList() : dbSystem.getDatabase().query(ServerQueries.fetchServersMatchingIdentifiers(serverNames));
|
List<ServerUUID> serverUUIDs = serverNames.isEmpty() ? Collections.emptyList() : dbSystem.getDatabase().query(ServerQueries.fetchServersMatchingIdentifiers(serverNames));
|
||||||
|
|
||||||
return dbSystem.getDatabase().query(UserInfoQueries.userIdsOfRegisteredBetween(0, System.currentTimeMillis(), serverUUIDs));
|
return dbSystem.getDatabase().query(UserInfoQueries.userIdsOfRegisteredBetween(0, System.currentTimeMillis(), serverUUIDs));
|
||||||
|
@ -26,7 +26,9 @@ import com.djrapitops.plan.storage.database.queries.QueryAllStatement;
|
|||||||
import com.djrapitops.plan.storage.database.queries.QueryStatement;
|
import com.djrapitops.plan.storage.database.queries.QueryStatement;
|
||||||
import com.djrapitops.plan.storage.database.queries.objects.ServerQueries;
|
import com.djrapitops.plan.storage.database.queries.objects.ServerQueries;
|
||||||
import com.djrapitops.plan.storage.database.sql.tables.*;
|
import com.djrapitops.plan.storage.database.sql.tables.*;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
@ -81,13 +83,13 @@ public class PluginBooleanGroupFilter extends MultiOptionFilter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static Query<Set<Integer>> playersInGroups(
|
private static Query<Set<Integer>> playersInGroups(
|
||||||
Map<PluginBooleanOption, SelectedBoolean> selected,
|
@Untrusted Map<PluginBooleanOption, SelectedBoolean> selected,
|
||||||
Map<String, ServerUUID> namesToUUIDs
|
Map<String, ServerUUID> namesToUUIDs
|
||||||
) {
|
) {
|
||||||
return db -> {
|
return db -> {
|
||||||
Set<Integer> userIds = new HashSet<>();
|
Set<Integer> userIds = new HashSet<>();
|
||||||
for (Map.Entry<PluginBooleanOption, SelectedBoolean> option : selected.entrySet()) {
|
for (Map.Entry<PluginBooleanOption, SelectedBoolean> option : selected.entrySet()) {
|
||||||
PluginBooleanOption pluginBooleanOption = option.getKey();
|
@Untrusted PluginBooleanOption pluginBooleanOption = option.getKey();
|
||||||
SelectedBoolean selectedBoolean = option.getValue();
|
SelectedBoolean selectedBoolean = option.getValue();
|
||||||
userIds.addAll(
|
userIds.addAll(
|
||||||
db.query(playersInGroup(
|
db.query(playersInGroup(
|
||||||
@ -103,8 +105,12 @@ public class PluginBooleanGroupFilter extends MultiOptionFilter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static Query<Set<Integer>> playersInGroup(
|
private static Query<Set<Integer>> playersInGroup(
|
||||||
ServerUUID serverUUID, String pluginName, String providerText, SelectedBoolean selectedBoolean
|
@Nullable ServerUUID serverUUID, @Untrusted String pluginName, @Untrusted String providerText, SelectedBoolean selectedBoolean
|
||||||
) {
|
) {
|
||||||
|
if (serverUUID == null) {
|
||||||
|
return db -> Collections.emptySet();
|
||||||
|
}
|
||||||
|
|
||||||
String selectUUIDsWithBooleanValues = SELECT + DISTINCT + "u." + UsersTable.ID + " as id" +
|
String selectUUIDsWithBooleanValues = SELECT + DISTINCT + "u." + UsersTable.ID + " as id" +
|
||||||
FROM + ExtensionPluginTable.TABLE_NAME + " plugin" +
|
FROM + ExtensionPluginTable.TABLE_NAME + " plugin" +
|
||||||
INNER_JOIN + ExtensionProviderTable.TABLE_NAME + " provider on provider." + ExtensionProviderTable.PLUGIN_ID + "=plugin." + ExtensionPluginTable.ID +
|
INNER_JOIN + ExtensionProviderTable.TABLE_NAME + " provider on provider." + ExtensionProviderTable.PLUGIN_ID + "=plugin." + ExtensionPluginTable.ID +
|
||||||
@ -162,12 +168,12 @@ public class PluginBooleanGroupFilter extends MultiOptionFilter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Integer> getMatchingUserIds(InputFilterDto query) {
|
public Set<Integer> getMatchingUserIds(@Untrusted InputFilterDto query) {
|
||||||
Map<PluginBooleanOption, SelectedBoolean> selectedBooleanOptions = new HashMap<>();
|
@Untrusted Map<PluginBooleanOption, SelectedBoolean> selectedBooleanOptions = new HashMap<>();
|
||||||
for (String selected : getSelected(query)) {
|
for (@Untrusted String selected : getSelected(query)) {
|
||||||
String[] optionAndBoolean = StringUtils.split(selected, ":", 2);
|
@Untrusted String[] optionAndBoolean = StringUtils.split(selected, ":", 2);
|
||||||
PluginBooleanOption pluginBooleanOption = PluginBooleanOption.parse(optionAndBoolean[0].trim());
|
@Untrusted PluginBooleanOption pluginBooleanOption = PluginBooleanOption.parse(optionAndBoolean[0].trim());
|
||||||
String selectedBoolean = optionAndBoolean[1].trim().toUpperCase();
|
@Untrusted String selectedBoolean = optionAndBoolean[1].trim().toUpperCase();
|
||||||
selectedBooleanOptions.computeIfPresent(pluginBooleanOption, (key, existing) -> SelectedBoolean.BOTH);
|
selectedBooleanOptions.computeIfPresent(pluginBooleanOption, (key, existing) -> SelectedBoolean.BOTH);
|
||||||
selectedBooleanOptions.computeIfAbsent(pluginBooleanOption, key -> SelectedBoolean.valueOf(selectedBoolean));
|
selectedBooleanOptions.computeIfAbsent(pluginBooleanOption, key -> SelectedBoolean.valueOf(selectedBoolean));
|
||||||
}
|
}
|
||||||
@ -183,6 +189,7 @@ public class PluginBooleanGroupFilter extends MultiOptionFilter {
|
|||||||
BOTH
|
BOTH
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Untrusted
|
||||||
public static class PluginBooleanOption implements Comparable<PluginBooleanOption> {
|
public static class PluginBooleanOption implements Comparable<PluginBooleanOption> {
|
||||||
private final String serverName;
|
private final String serverName;
|
||||||
private final String pluginName;
|
private final String pluginName;
|
||||||
@ -194,12 +201,13 @@ public class PluginBooleanGroupFilter extends MultiOptionFilter {
|
|||||||
this.providerText = providerText;
|
this.providerText = providerText;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PluginBooleanOption parse(String fromFormatted) {
|
@Untrusted
|
||||||
String[] split1 = StringUtils.split(fromFormatted, ",", 2);
|
public static PluginBooleanOption parse(@Untrusted String fromFormatted) {
|
||||||
String[] split2 = StringUtils.split(split1[1], "-", 2);
|
@Untrusted String[] split1 = StringUtils.split(fromFormatted, ",", 2);
|
||||||
String serverName = split1[0].trim();
|
@Untrusted String[] split2 = StringUtils.split(split1[1], "-", 2);
|
||||||
String pluginName = split2[0].trim();
|
@Untrusted String serverName = split1[0].trim();
|
||||||
String providerName = split2[1].trim();
|
@Untrusted String pluginName = split2[0].trim();
|
||||||
|
@Untrusted String providerName = split2[1].trim();
|
||||||
return new PluginBooleanOption(serverName, pluginName, providerName);
|
return new PluginBooleanOption(serverName, pluginName, providerName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ import com.djrapitops.plan.storage.database.sql.tables.ExtensionGroupsTable;
|
|||||||
import com.djrapitops.plan.storage.database.sql.tables.ExtensionPluginTable;
|
import com.djrapitops.plan.storage.database.sql.tables.ExtensionPluginTable;
|
||||||
import com.djrapitops.plan.storage.database.sql.tables.ExtensionProviderTable;
|
import com.djrapitops.plan.storage.database.sql.tables.ExtensionProviderTable;
|
||||||
import com.djrapitops.plan.storage.database.sql.tables.ServerTable;
|
import com.djrapitops.plan.storage.database.sql.tables.ServerTable;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
import com.djrapitops.plan.utilities.java.Maps;
|
import com.djrapitops.plan.utilities.java.Maps;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
@ -67,7 +68,7 @@ public class PluginGroupsFilter extends MultiOptionFilter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Integer> getMatchingUserIds(InputFilterDto query) {
|
public Set<Integer> getMatchingUserIds(@Untrusted InputFilterDto query) {
|
||||||
return dbSystem.getDatabase().query(
|
return dbSystem.getDatabase().query(
|
||||||
new ExtensionUserIdsInGroupQuery(identifier.getPluginName(), identifier.getProviderName(), identifier.getServerUUID(), getSelected(query))
|
new ExtensionUserIdsInGroupQuery(identifier.getPluginName(), identifier.getProviderName(), identifier.getServerUUID(), getSelected(query))
|
||||||
);
|
);
|
||||||
|
@ -22,6 +22,7 @@ import com.djrapitops.plan.storage.database.DBSystem;
|
|||||||
import com.djrapitops.plan.storage.database.queries.objects.BaseUserQueries;
|
import com.djrapitops.plan.storage.database.queries.objects.BaseUserQueries;
|
||||||
import com.djrapitops.plan.storage.database.queries.objects.ServerQueries;
|
import com.djrapitops.plan.storage.database.queries.objects.ServerQueries;
|
||||||
import com.djrapitops.plan.storage.database.queries.objects.UserInfoQueries;
|
import com.djrapitops.plan.storage.database.queries.objects.UserInfoQueries;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
@ -48,10 +49,10 @@ public class RegisteredBetweenDateRangeFilter extends DateRangeFilter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Integer> getMatchingUserIds(InputFilterDto query) {
|
public Set<Integer> getMatchingUserIds(@Untrusted InputFilterDto query) {
|
||||||
long after = getAfter(query);
|
long after = getAfter(query);
|
||||||
long before = getBefore(query);
|
long before = getBefore(query);
|
||||||
List<String> serverNames = getServerNames(query);
|
@Untrusted List<String> serverNames = getServerNames(query);
|
||||||
List<ServerUUID> serverUUIDs = serverNames.isEmpty() ? Collections.emptyList() : dbSystem.getDatabase().query(ServerQueries.fetchServersMatchingIdentifiers(serverNames));
|
List<ServerUUID> serverUUIDs = serverNames.isEmpty() ? Collections.emptyList() : dbSystem.getDatabase().query(ServerQueries.fetchServersMatchingIdentifiers(serverNames));
|
||||||
return dbSystem.getDatabase().query(
|
return dbSystem.getDatabase().query(
|
||||||
serverUUIDs.isEmpty() ? BaseUserQueries.userIdsOfRegisteredBetween(after, before)
|
serverUUIDs.isEmpty() ? BaseUserQueries.userIdsOfRegisteredBetween(after, before)
|
||||||
@ -59,7 +60,7 @@ public class RegisteredBetweenDateRangeFilter extends DateRangeFilter {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<String> getServerNames(InputFilterDto query) {
|
private List<String> getServerNames(@Untrusted InputFilterDto query) {
|
||||||
return query.get("servers")
|
return query.get("servers")
|
||||||
.map(serversList -> new Gson().fromJson(serversList, String[].class))
|
.map(serversList -> new Gson().fromJson(serversList, String[].class))
|
||||||
.map(Arrays::asList)
|
.map(Arrays::asList)
|
||||||
|
@ -21,10 +21,12 @@ import com.djrapitops.plan.identification.ServerUUID;
|
|||||||
import com.djrapitops.plan.storage.database.queries.Query;
|
import com.djrapitops.plan.storage.database.queries.Query;
|
||||||
import com.djrapitops.plan.storage.database.queries.QueryAllStatement;
|
import com.djrapitops.plan.storage.database.queries.QueryAllStatement;
|
||||||
import com.djrapitops.plan.storage.database.queries.RowExtractors;
|
import com.djrapitops.plan.storage.database.queries.RowExtractors;
|
||||||
|
import com.djrapitops.plan.storage.database.sql.building.Sql;
|
||||||
import com.djrapitops.plan.storage.database.sql.tables.GeoInfoTable;
|
import com.djrapitops.plan.storage.database.sql.tables.GeoInfoTable;
|
||||||
import com.djrapitops.plan.storage.database.sql.tables.ServerTable;
|
import com.djrapitops.plan.storage.database.sql.tables.ServerTable;
|
||||||
import com.djrapitops.plan.storage.database.sql.tables.UserInfoTable;
|
import com.djrapitops.plan.storage.database.sql.tables.UserInfoTable;
|
||||||
import com.djrapitops.plan.storage.database.sql.tables.UsersTable;
|
import com.djrapitops.plan.storage.database.sql.tables.UsersTable;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
import com.djrapitops.plan.utilities.java.Lists;
|
import com.djrapitops.plan.utilities.java.Lists;
|
||||||
import org.apache.commons.text.TextStringBuilder;
|
import org.apache.commons.text.TextStringBuilder;
|
||||||
|
|
||||||
@ -166,14 +168,12 @@ public class GeoInfoQueries {
|
|||||||
return db -> db.queryList(sql, RowExtractors.getString(GeoInfoTable.GEOLOCATION));
|
return db -> db.queryList(sql, RowExtractors.getString(GeoInfoTable.GEOLOCATION));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Query<Set<Integer>> userIdsOfPlayersWithGeolocations(List<String> selected) {
|
public static Query<Set<Integer>> userIdsOfPlayersWithGeolocations(@Untrusted List<String> selected) {
|
||||||
String sql = SELECT + "u." + UsersTable.ID +
|
String sql = SELECT + "u." + UsersTable.ID +
|
||||||
FROM + GeoInfoTable.TABLE_NAME + " g" +
|
FROM + GeoInfoTable.TABLE_NAME + " g" +
|
||||||
INNER_JOIN + UsersTable.TABLE_NAME + " u on u.id=g." + GeoInfoTable.USER_ID +
|
INNER_JOIN + UsersTable.TABLE_NAME + " u on u.id=g." + GeoInfoTable.USER_ID +
|
||||||
WHERE + GeoInfoTable.GEOLOCATION +
|
WHERE + GeoInfoTable.GEOLOCATION +
|
||||||
" IN ('" +
|
" IN (" + Sql.nParameters(selected.size()) + ")";
|
||||||
new TextStringBuilder().appendWithSeparators(selected, "','") +
|
return db -> db.querySet(sql, RowExtractors.getInt(UsersTable.ID), selected);
|
||||||
"')";
|
|
||||||
return db -> db.querySet(sql, RowExtractors.getInt(UsersTable.ID));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -26,7 +26,7 @@ import com.djrapitops.plan.storage.database.sql.building.Sql;
|
|||||||
import com.djrapitops.plan.storage.database.sql.tables.JoinAddressTable;
|
import com.djrapitops.plan.storage.database.sql.tables.JoinAddressTable;
|
||||||
import com.djrapitops.plan.storage.database.sql.tables.ServerTable;
|
import com.djrapitops.plan.storage.database.sql.tables.ServerTable;
|
||||||
import com.djrapitops.plan.storage.database.sql.tables.SessionsTable;
|
import com.djrapitops.plan.storage.database.sql.tables.SessionsTable;
|
||||||
import org.apache.commons.text.TextStringBuilder;
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
|
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
@ -104,12 +104,12 @@ public class JoinAddressQueries {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Query<Set<Integer>> userIdsOfPlayersWithJoinAddresses(List<String> joinAddresses) {
|
public static Query<Set<Integer>> userIdsOfPlayersWithJoinAddresses(@Untrusted List<String> joinAddresses) {
|
||||||
String sql = SELECT + DISTINCT + SessionsTable.USER_ID +
|
String sql = SELECT + DISTINCT + SessionsTable.USER_ID +
|
||||||
FROM + JoinAddressTable.TABLE_NAME + " j" +
|
FROM + JoinAddressTable.TABLE_NAME + " j" +
|
||||||
INNER_JOIN + SessionsTable.TABLE_NAME + " s on s." + SessionsTable.JOIN_ADDRESS_ID + "=j." + JoinAddressTable.ID +
|
INNER_JOIN + SessionsTable.TABLE_NAME + " s on s." + SessionsTable.JOIN_ADDRESS_ID + "=j." + JoinAddressTable.ID +
|
||||||
WHERE + JoinAddressTable.JOIN_ADDRESS + " IN (" +
|
WHERE + JoinAddressTable.JOIN_ADDRESS + " IN (" +
|
||||||
new TextStringBuilder().appendWithSeparators(joinAddresses.stream().map(item -> '?').iterator(), ",") +
|
nParameters(joinAddresses.size()) +
|
||||||
')'; // Don't append addresses directly, SQL injection hazard
|
')'; // Don't append addresses directly, SQL injection hazard
|
||||||
|
|
||||||
return db -> db.querySet(sql, RowExtractors.getInt(SessionsTable.USER_ID), joinAddresses.toArray());
|
return db -> db.querySet(sql, RowExtractors.getInt(SessionsTable.USER_ID), joinAddresses.toArray());
|
||||||
|
@ -23,6 +23,7 @@ import com.djrapitops.plan.storage.database.queries.QueryAllStatement;
|
|||||||
import com.djrapitops.plan.storage.database.queries.QueryStatement;
|
import com.djrapitops.plan.storage.database.queries.QueryStatement;
|
||||||
import com.djrapitops.plan.storage.database.sql.building.Select;
|
import com.djrapitops.plan.storage.database.sql.building.Select;
|
||||||
import com.djrapitops.plan.storage.database.sql.tables.ServerTable;
|
import com.djrapitops.plan.storage.database.sql.tables.ServerTable;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
import com.djrapitops.plan.utilities.java.Maps;
|
import com.djrapitops.plan.utilities.java.Maps;
|
||||||
import org.apache.commons.lang3.math.NumberUtils;
|
import org.apache.commons.lang3.math.NumberUtils;
|
||||||
|
|
||||||
@ -110,7 +111,7 @@ public class ServerQueries {
|
|||||||
return fetchServerMatchingIdentifier(serverUUID.toString());
|
return fetchServerMatchingIdentifier(serverUUID.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Query<Optional<Server>> fetchServerMatchingIdentifier(String identifier) {
|
public static Query<Optional<Server>> fetchServerMatchingIdentifier(@Untrusted String identifier) {
|
||||||
String sql = SELECT + '*' + FROM + ServerTable.TABLE_NAME +
|
String sql = SELECT + '*' + FROM + ServerTable.TABLE_NAME +
|
||||||
WHERE + "(LOWER(" + ServerTable.SERVER_UUID + ") LIKE LOWER(?)" +
|
WHERE + "(LOWER(" + ServerTable.SERVER_UUID + ") LIKE LOWER(?)" +
|
||||||
OR + "LOWER(" + ServerTable.NAME + ") LIKE LOWER(?)" +
|
OR + "LOWER(" + ServerTable.NAME + ") LIKE LOWER(?)" +
|
||||||
@ -283,7 +284,7 @@ public class ServerQueries {
|
|||||||
return db -> Maps.reverse(db.query(fetchServerNames()));
|
return db -> Maps.reverse(db.query(fetchServerNames()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Query<List<ServerUUID>> fetchServersMatchingIdentifiers(List<String> serverNames) {
|
public static Query<List<ServerUUID>> fetchServersMatchingIdentifiers(@Untrusted List<String> serverNames) {
|
||||||
return db -> {
|
return db -> {
|
||||||
Map<String, ServerUUID> nameToUUIDMap = db.query(ServerQueries.fetchServerNamesToUUIDs());
|
Map<String, ServerUUID> nameToUUIDMap = db.query(ServerQueries.fetchServerNamesToUUIDs());
|
||||||
return serverNames.stream()
|
return serverNames.stream()
|
||||||
|
@ -23,7 +23,7 @@ import com.djrapitops.plan.identification.ServerUUID;
|
|||||||
import com.djrapitops.plan.storage.database.queries.Query;
|
import com.djrapitops.plan.storage.database.queries.Query;
|
||||||
import com.djrapitops.plan.storage.database.queries.QueryStatement;
|
import com.djrapitops.plan.storage.database.queries.QueryStatement;
|
||||||
import com.djrapitops.plan.storage.database.sql.tables.ServerTable;
|
import com.djrapitops.plan.storage.database.sql.tables.ServerTable;
|
||||||
import com.djrapitops.plan.utilities.Benchmark;
|
import com.djrapitops.plan.utilities.dev.Benchmark;
|
||||||
import com.djrapitops.plan.utilities.java.Lists;
|
import com.djrapitops.plan.utilities.java.Lists;
|
||||||
|
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
|
@ -25,6 +25,7 @@ import com.djrapitops.plan.storage.database.sql.tables.NicknamesTable;
|
|||||||
import com.djrapitops.plan.storage.database.sql.tables.ServerTable;
|
import com.djrapitops.plan.storage.database.sql.tables.ServerTable;
|
||||||
import com.djrapitops.plan.storage.database.sql.tables.UserInfoTable;
|
import com.djrapitops.plan.storage.database.sql.tables.UserInfoTable;
|
||||||
import com.djrapitops.plan.storage.database.sql.tables.UsersTable;
|
import com.djrapitops.plan.storage.database.sql.tables.UsersTable;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
|
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
@ -125,7 +126,7 @@ public class UserIdentifierQueries {
|
|||||||
* @param playerName Name of the player, case does not matter.
|
* @param playerName Name of the player, case does not matter.
|
||||||
* @return Optional: UUID if found, empty if not.
|
* @return Optional: UUID if found, empty if not.
|
||||||
*/
|
*/
|
||||||
public static Query<Optional<UUID>> fetchPlayerUUIDOf(String playerName) {
|
public static Query<Optional<UUID>> fetchPlayerUUIDOf(@Untrusted String playerName) {
|
||||||
String sql = Select.from(UsersTable.TABLE_NAME, UsersTable.USER_UUID)
|
String sql = Select.from(UsersTable.TABLE_NAME, UsersTable.USER_UUID)
|
||||||
.where("UPPER(" + UsersTable.USER_NAME + ")=UPPER(?)")
|
.where("UPPER(" + UsersTable.USER_NAME + ")=UPPER(?)")
|
||||||
.toString();
|
.toString();
|
||||||
@ -172,7 +173,7 @@ public class UserIdentifierQueries {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Query<List<String>> fetchMatchingPlayerNames(String searchFor) {
|
public static Query<List<String>> fetchMatchingPlayerNames(@Untrusted String searchFor) {
|
||||||
String sql = SELECT + DISTINCT + UsersTable.USER_NAME +
|
String sql = SELECT + DISTINCT + UsersTable.USER_NAME +
|
||||||
FROM + UsersTable.TABLE_NAME +
|
FROM + UsersTable.TABLE_NAME +
|
||||||
WHERE + "LOWER(" + UsersTable.USER_NAME + ") LIKE LOWER(?)" +
|
WHERE + "LOWER(" + UsersTable.USER_NAME + ") LIKE LOWER(?)" +
|
||||||
|
@ -22,6 +22,7 @@ import com.djrapitops.plan.storage.database.queries.Query;
|
|||||||
import com.djrapitops.plan.storage.database.sql.tables.CookieTable;
|
import com.djrapitops.plan.storage.database.sql.tables.CookieTable;
|
||||||
import com.djrapitops.plan.storage.database.sql.tables.SecurityTable;
|
import com.djrapitops.plan.storage.database.sql.tables.SecurityTable;
|
||||||
import com.djrapitops.plan.storage.database.sql.tables.UsersTable;
|
import com.djrapitops.plan.storage.database.sql.tables.UsersTable;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
|
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
@ -43,7 +44,7 @@ public class WebUserQueries {
|
|||||||
/* Static method class */
|
/* Static method class */
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Query<Optional<User>> fetchUser(String username) {
|
public static Query<Optional<User>> fetchUser(@Untrusted String username) {
|
||||||
String sql = SELECT + '*' + FROM + SecurityTable.TABLE_NAME +
|
String sql = SELECT + '*' + FROM + SecurityTable.TABLE_NAME +
|
||||||
LEFT_JOIN + UsersTable.TABLE_NAME + " on " + SecurityTable.LINKED_TO + "=" + UsersTable.USER_UUID +
|
LEFT_JOIN + UsersTable.TABLE_NAME + " on " + SecurityTable.LINKED_TO + "=" + UsersTable.USER_UUID +
|
||||||
WHERE + SecurityTable.USERNAME + "=?" + LIMIT + "1";
|
WHERE + SecurityTable.USERNAME + "=?" + LIMIT + "1";
|
||||||
|
@ -19,6 +19,7 @@ package com.djrapitops.plan.storage.database.transactions.events;
|
|||||||
import com.djrapitops.plan.storage.database.sql.tables.CookieTable;
|
import com.djrapitops.plan.storage.database.sql.tables.CookieTable;
|
||||||
import com.djrapitops.plan.storage.database.transactions.ExecStatement;
|
import com.djrapitops.plan.storage.database.transactions.ExecStatement;
|
||||||
import com.djrapitops.plan.storage.database.transactions.Transaction;
|
import com.djrapitops.plan.storage.database.transactions.Transaction;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
|
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
@ -26,10 +27,11 @@ import java.sql.SQLException;
|
|||||||
public class CookieChangeTransaction extends Transaction {
|
public class CookieChangeTransaction extends Transaction {
|
||||||
|
|
||||||
private final String username;
|
private final String username;
|
||||||
|
@Untrusted
|
||||||
private final String cookie; // Null if removing
|
private final String cookie; // Null if removing
|
||||||
private final Long expires;
|
private final Long expires;
|
||||||
|
|
||||||
private CookieChangeTransaction(String username, String cookie, Long expires) {
|
private CookieChangeTransaction(String username, @Untrusted String cookie, Long expires) {
|
||||||
this.username = username;
|
this.username = username;
|
||||||
this.cookie = cookie;
|
this.cookie = cookie;
|
||||||
this.expires = expires;
|
this.expires = expires;
|
||||||
@ -43,7 +45,7 @@ public class CookieChangeTransaction extends Transaction {
|
|||||||
return new CookieChangeTransaction(username, null, null);
|
return new CookieChangeTransaction(username, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CookieChangeTransaction removeCookie(String cookie) {
|
public static CookieChangeTransaction removeCookie(@Untrusted String cookie) {
|
||||||
return new CookieChangeTransaction(null, cookie, null);
|
return new CookieChangeTransaction(null, cookie, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@ import com.djrapitops.plan.storage.database.queries.Query;
|
|||||||
import com.djrapitops.plan.storage.database.sql.tables.JoinAddressTable;
|
import com.djrapitops.plan.storage.database.sql.tables.JoinAddressTable;
|
||||||
import com.djrapitops.plan.storage.database.transactions.ExecStatement;
|
import com.djrapitops.plan.storage.database.transactions.ExecStatement;
|
||||||
import com.djrapitops.plan.storage.database.transactions.Transaction;
|
import com.djrapitops.plan.storage.database.transactions.Transaction;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
@ -33,10 +34,11 @@ import static com.djrapitops.plan.storage.database.sql.building.Sql.*;
|
|||||||
|
|
||||||
public class StoreJoinAddressTransaction extends Transaction {
|
public class StoreJoinAddressTransaction extends Transaction {
|
||||||
|
|
||||||
|
@Untrusted
|
||||||
private final Supplier<String> joinAddress;
|
private final Supplier<String> joinAddress;
|
||||||
private int newId;
|
private int newId;
|
||||||
|
|
||||||
public StoreJoinAddressTransaction(String joinAddress) {
|
public StoreJoinAddressTransaction(@Untrusted String joinAddress) {
|
||||||
this(() -> joinAddress);
|
this(() -> joinAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,12 +58,13 @@ public class StoreJoinAddressTransaction extends Transaction {
|
|||||||
return new HasMoreThanZeroQueryStatement(sql) {
|
return new HasMoreThanZeroQueryStatement(sql) {
|
||||||
@Override
|
@Override
|
||||||
public void prepare(PreparedStatement statement) throws SQLException {
|
public void prepare(PreparedStatement statement) throws SQLException {
|
||||||
String address = getAddress();
|
@Untrusted String address = getAddress();
|
||||||
statement.setString(1, address);
|
statement.setString(1, address);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Untrusted
|
||||||
private String getAddress() {
|
private String getAddress() {
|
||||||
return StringUtils.truncate(joinAddress.get(), JoinAddressTable.JOIN_ADDRESS_MAX_LENGTH);
|
return StringUtils.truncate(joinAddress.get(), JoinAddressTable.JOIN_ADDRESS_MAX_LENGTH);
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ import com.djrapitops.plan.SubSystem;
|
|||||||
import com.djrapitops.plan.exceptions.EnableException;
|
import com.djrapitops.plan.exceptions.EnableException;
|
||||||
import com.djrapitops.plan.settings.config.PlanConfig;
|
import com.djrapitops.plan.settings.config.PlanConfig;
|
||||||
import com.djrapitops.plan.settings.config.paths.CustomizedFileSettings;
|
import com.djrapitops.plan.settings.config.paths.CustomizedFileSettings;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
import dagger.Lazy;
|
import dagger.Lazy;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
@ -90,7 +91,7 @@ public class PlanFiles implements SubSystem {
|
|||||||
return getFileFromPluginFolder("locale.yml");
|
return getFileFromPluginFolder("locale.yml");
|
||||||
}
|
}
|
||||||
|
|
||||||
public File getFileFromPluginFolder(String name) {
|
public File getFileFromPluginFolder(@Untrusted String name) {
|
||||||
return new File(dataFolder, name.replace("/", File.separator));
|
return new File(dataFolder, name.replace("/", File.separator));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
package com.djrapitops.plan.utilities;
|
package com.djrapitops.plan.utilities;
|
||||||
|
|
||||||
import com.djrapitops.plan.exceptions.PassEncryptException;
|
import com.djrapitops.plan.exceptions.PassEncryptException;
|
||||||
|
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import javax.crypto.SecretKeyFactory;
|
import javax.crypto.SecretKeyFactory;
|
||||||
@ -62,7 +63,7 @@ public class PassEncryptUtil {
|
|||||||
* @return Hash + salt
|
* @return Hash + salt
|
||||||
* @throws CannotPerformOperationException If the hash creation fails
|
* @throws CannotPerformOperationException If the hash creation fails
|
||||||
*/
|
*/
|
||||||
public static String createHash(String password) {
|
public static String createHash(@Untrusted String password) {
|
||||||
return createHash(password.toCharArray());
|
return createHash(password.toCharArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,7 +94,7 @@ public class PassEncryptUtil {
|
|||||||
* @throws CannotPerformOperationException If hashing fails
|
* @throws CannotPerformOperationException If hashing fails
|
||||||
* @throws InvalidHashException If the hash is missing details.
|
* @throws InvalidHashException If the hash is missing details.
|
||||||
*/
|
*/
|
||||||
public static boolean verifyPassword(String password, String correctHash) {
|
public static boolean verifyPassword(@Untrusted String password, String correctHash) {
|
||||||
return verifyPassword(password.toCharArray(), correctHash);
|
return verifyPassword(password.toCharArray(), correctHash);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
* You should have received a copy of the GNU Lesser General Public License
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
|
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.djrapitops.plan.utilities;
|
package com.djrapitops.plan.utilities.dev;
|
||||||
|
|
||||||
import com.djrapitops.plan.delivery.formatting.Formatter;
|
import com.djrapitops.plan.delivery.formatting.Formatter;
|
||||||
|
|
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Player Analytics (Plan).
|
||||||
|
*
|
||||||
|
* Plan is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License v3 as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Plan is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package com.djrapitops.plan.utilities.dev;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Annotation for identifying untrusted data that has not been sanitized.
|
||||||
|
*
|
||||||
|
* @author AuroraLS3
|
||||||
|
*/
|
||||||
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
|
@Target({ElementType.PARAMETER, ElementType.FIELD, ElementType.METHOD, ElementType.LOCAL_VARIABLE, ElementType.TYPE_PARAMETER, ElementType.TYPE_USE, ElementType.CONSTRUCTOR, ElementType.TYPE})
|
||||||
|
public @interface Untrusted {}
|
Loading…
Reference in New Issue
Block a user