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.placeholder.PlanPlaceholders;
|
||||
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.ErrorLogger;
|
||||
import com.djrapitops.plan.version.VersionChecker;
|
||||
@ -89,7 +90,7 @@ public class PlanPlaceholderExtension extends PlaceholderExpansion {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onRequest(OfflinePlayer player, String params) {
|
||||
public String onRequest(OfflinePlayer player, @Untrusted String params) {
|
||||
UUID uuid = player != null ? player.getUniqueId() : null;
|
||||
if ("Server thread".equalsIgnoreCase(Thread.currentThread().getName())) {
|
||||
return getCached(params, uuid);
|
||||
@ -97,7 +98,7 @@ public class PlanPlaceholderExtension extends PlaceholderExpansion {
|
||||
return getPlaceholderValue(params, uuid);
|
||||
}
|
||||
|
||||
private String getPlaceholderValue(String params, UUID uuid) {
|
||||
private String getPlaceholderValue(@Untrusted String params, UUID uuid) {
|
||||
try {
|
||||
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];
|
||||
}
|
||||
|
||||
private List<String> parseParameters(String params) {
|
||||
@Untrusted
|
||||
private List<String> parseParameters(@Untrusted String params) {
|
||||
List<String> parameters = new ArrayList<>();
|
||||
boolean first = true;
|
||||
for (String parameter : params.split(":")) {
|
||||
for (@Untrusted String parameter : params.split(":")) {
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
@ -131,8 +134,8 @@ public class PlanPlaceholderExtension extends PlaceholderExpansion {
|
||||
return parameters;
|
||||
}
|
||||
|
||||
private String getCached(String params, UUID uuid) {
|
||||
String key = params + "-" + uuid;
|
||||
private String getCached(@Untrusted String params, UUID uuid) {
|
||||
@Untrusted String key = params + "-" + uuid;
|
||||
|
||||
if (!currentlyProcessing.contains(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.HelpLang;
|
||||
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.ErrorLogger;
|
||||
|
||||
@ -84,7 +85,7 @@ public class PlanCommand {
|
||||
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) {
|
||||
sender.send("§c" + error.getMessage());
|
||||
} else {
|
||||
@ -131,13 +132,13 @@ public class PlanCommand {
|
||||
return command;
|
||||
}
|
||||
|
||||
public List<String> serverNames(CMDSender sender, Arguments arguments) {
|
||||
String asString = arguments.concatenate(" ");
|
||||
public List<String> serverNames(CMDSender sender, @Untrusted Arguments arguments) {
|
||||
@Untrusted String asString = arguments.concatenate(" ");
|
||||
return tabCompleteCache.getMatchingServerIdentifiers(asString);
|
||||
}
|
||||
|
||||
private List<String> playerNames(CMDSender sender, Arguments arguments) {
|
||||
String asString = arguments.concatenate(" ");
|
||||
private List<String> playerNames(CMDSender sender, @Untrusted Arguments arguments) {
|
||||
@Untrusted String asString = arguments.concatenate(" ");
|
||||
return tabCompleteCache.getMatchingPlayerIdentifiers(asString);
|
||||
}
|
||||
|
||||
@ -254,12 +255,12 @@ public class PlanCommand {
|
||||
.build();
|
||||
}
|
||||
|
||||
private List<String> webUserNames(CMDSender sender, Arguments arguments) {
|
||||
private List<String> webUserNames(CMDSender sender, @Untrusted Arguments arguments) {
|
||||
if (!sender.hasPermission(Permissions.UNREGISTER_OTHER)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
String username = arguments.concatenate(" ");
|
||||
@Untrusted String username = arguments.concatenate(" ");
|
||||
return tabCompleteCache.getMatchingUserIdentifiers(username);
|
||||
}
|
||||
|
||||
@ -388,15 +389,15 @@ public class PlanCommand {
|
||||
.build();
|
||||
}
|
||||
|
||||
private List<String> getBackupFilenames(CMDSender sender, Arguments arguments) {
|
||||
private List<String> getBackupFilenames(CMDSender sender, @Untrusted Arguments arguments) {
|
||||
if (arguments.get(1).isPresent()) {
|
||||
return DBType.names();
|
||||
}
|
||||
Optional<String> firstArgument = arguments.get(0);
|
||||
@Untrusted Optional<String> firstArgument = arguments.get(0);
|
||||
if (firstArgument.isEmpty()) {
|
||||
return tabCompleteCache.getMatchingBackupFilenames(null);
|
||||
}
|
||||
String part = firstArgument.get();
|
||||
@Untrusted String part = firstArgument.get();
|
||||
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.WebUserQueries;
|
||||
import com.djrapitops.plan.storage.file.PlanFiles;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.inject.Inject;
|
||||
@ -115,25 +116,25 @@ public class TabCompleteCache implements SubSystem {
|
||||
backupFileNames.clear();
|
||||
}
|
||||
|
||||
public List<String> getMatchingServerIdentifiers(String searchFor) {
|
||||
public List<String> getMatchingServerIdentifiers(@Untrusted String searchFor) {
|
||||
return findMatches(serverIdentifiers, searchFor);
|
||||
}
|
||||
|
||||
public List<String> getMatchingPlayerIdentifiers(String searchFor) {
|
||||
public List<String> getMatchingPlayerIdentifiers(@Untrusted String searchFor) {
|
||||
playerIdentifiers.addAll(serverSensor.getOnlinePlayerNames());
|
||||
return findMatches(playerIdentifiers, searchFor);
|
||||
}
|
||||
|
||||
public List<String> getMatchingUserIdentifiers(String searchFor) {
|
||||
public List<String> getMatchingUserIdentifiers(@Untrusted String searchFor) {
|
||||
return findMatches(userIdentifiers, searchFor);
|
||||
}
|
||||
|
||||
public List<String> getMatchingBackupFilenames(String searchFor) {
|
||||
public List<String> getMatchingBackupFilenames(@Untrusted String searchFor) {
|
||||
return findMatches(backupFileNames, searchFor);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
List<String> findMatches(Collection<String> searchList, String searchFor) {
|
||||
List<String> findMatches(Collection<String> searchList, @Untrusted String searchFor) {
|
||||
List<String> filtered = searchList.stream()
|
||||
.filter(identifier -> searchFor == null || searchFor.isEmpty() || identifier.startsWith(searchFor))
|
||||
.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.queries.containers.ContainerFetchQueries;
|
||||
import com.djrapitops.plan.storage.database.queries.objects.UserIdentifierQueries;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
@ -95,8 +96,8 @@ public class DataUtilityCommands {
|
||||
}
|
||||
}
|
||||
|
||||
public void onExport(CMDSender sender, Arguments arguments) {
|
||||
String exportKind = arguments.get(0)
|
||||
public void onExport(CMDSender sender, @Untrusted Arguments arguments) {
|
||||
@Untrusted String exportKind = arguments.get(0)
|
||||
.orElseThrow(() -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_ACCEPTS_ARGUMENTS, locale.getString(HelpLang.ARG_EXPORT_KIND), "players, server_json")));
|
||||
|
||||
ensureDatabaseIsOpen();
|
||||
@ -104,7 +105,7 @@ public class DataUtilityCommands {
|
||||
getExportFunction(exportKind).accept(sender);
|
||||
}
|
||||
|
||||
private Consumer<CMDSender> getExportFunction(String exportArg) {
|
||||
private Consumer<CMDSender> getExportFunction(@Untrusted String exportArg) {
|
||||
if ("players".equals(exportArg)) {
|
||||
return this::exportPlayers;
|
||||
} else if ("server_json".endsWith(exportArg)) {
|
||||
@ -176,8 +177,8 @@ public class DataUtilityCommands {
|
||||
}
|
||||
}
|
||||
|
||||
public void onImport(CMDSender sender, Arguments arguments) {
|
||||
String importKind = arguments.get(0)
|
||||
public void onImport(CMDSender sender, @Untrusted Arguments arguments) {
|
||||
@Untrusted String importKind = arguments.get(0)
|
||||
.orElseThrow(() -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_ACCEPTS_ARGUMENTS, locale.getString(HelpLang.ARG_IMPORT_KIND), importSystem.getImporterNames().toString())));
|
||||
|
||||
ensureDatabaseIsOpen();
|
||||
@ -185,7 +186,7 @@ public class DataUtilityCommands {
|
||||
findAndProcessImporter(sender, importKind);
|
||||
}
|
||||
|
||||
private void findAndProcessImporter(CMDSender sender, String importKind) {
|
||||
private void findAndProcessImporter(CMDSender sender, @Untrusted String importKind) {
|
||||
Optional<Importer> foundImporter = importSystem.getImporter(importKind);
|
||||
if (foundImporter.isPresent()) {
|
||||
Importer importer = foundImporter.get();
|
||||
@ -199,8 +200,8 @@ public class DataUtilityCommands {
|
||||
}
|
||||
}
|
||||
|
||||
public void onSearch(CMDSender sender, Arguments arguments) {
|
||||
String searchingFor = arguments.concatenate(" ");
|
||||
public void onSearch(CMDSender sender, @Untrusted Arguments arguments) {
|
||||
@Untrusted String searchingFor = arguments.concatenate(" ");
|
||||
if (searchingFor.trim().isEmpty()) {
|
||||
throw new IllegalArgumentException(locale.getString(CommandLang.FAIL_EMPTY_SEARCH_STRING));
|
||||
}
|
||||
@ -221,8 +222,8 @@ public class DataUtilityCommands {
|
||||
sender.send(sender.getFormatter().table(asTableString.toString(), "::"));
|
||||
}
|
||||
|
||||
public void onInGame(CMDSender sender, Arguments arguments) {
|
||||
String identifier = arguments.concatenate(" ");
|
||||
public void onInGame(CMDSender sender, @Untrusted Arguments arguments) {
|
||||
@Untrusted String identifier = arguments.concatenate(" ");
|
||||
UUID playerUUID = identifiers.getPlayerUUID(identifier);
|
||||
UUID senderUUID = sender.getUUID().orElse(null);
|
||||
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.patches.BadFabricJoinAddressValuePatch;
|
||||
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.ErrorLogger;
|
||||
import net.playeranalytics.plugin.player.UUIDFetcher;
|
||||
@ -113,7 +114,7 @@ public class DatabaseCommands {
|
||||
this.processing = processing;
|
||||
}
|
||||
|
||||
public void onBackup(CMDSender sender, Arguments arguments) {
|
||||
public void onBackup(CMDSender sender, @Untrusted Arguments arguments) {
|
||||
String dbName = arguments.get(0)
|
||||
.orElse(dbSystem.getDatabase().getType().getName())
|
||||
.toLowerCase();
|
||||
@ -129,7 +130,7 @@ public class DatabaseCommands {
|
||||
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;
|
||||
try {
|
||||
String timeStamp = timestamp.apply(System.currentTimeMillis());
|
||||
@ -150,8 +151,8 @@ public class DatabaseCommands {
|
||||
}
|
||||
}
|
||||
|
||||
public void onRestore(String mainCommand, CMDSender sender, Arguments arguments) {
|
||||
String backupDbName = arguments.get(0)
|
||||
public void onRestore(String mainCommand, CMDSender sender, @Untrusted Arguments arguments) {
|
||||
@Untrusted String backupDbName = arguments.get(0)
|
||||
.orElseThrow(() -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_REQ_ARGS, 1, "<" + locale.getString(HelpLang.ARG_BACKUP_FILE) + ">")));
|
||||
|
||||
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)
|
||||
.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)
|
||||
.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) {
|
||||
String identifier = arguments.concatenate(" ");
|
||||
public void onFixFabricJoinAddresses(String mainCommand, CMDSender sender, @Untrusted Arguments arguments) {
|
||||
@Untrusted String identifier = arguments.concatenate(" ");
|
||||
Optional<ServerUUID> serverUUID = identifiers.getServerUUID(identifier);
|
||||
if (serverUUID.isEmpty()) {
|
||||
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) {
|
||||
String identifier = arguments.concatenate(" ");
|
||||
public void onRemove(String mainCommand, CMDSender sender, @Untrusted Arguments arguments) {
|
||||
@Untrusted String identifier = arguments.concatenate(" ");
|
||||
UUID playerUUID = identifiers.getPlayerUUID(identifier);
|
||||
if (playerUUID == null) {
|
||||
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();
|
||||
String identifier = arguments.concatenate(" ");
|
||||
@Untrusted String identifier = arguments.concatenate(" ");
|
||||
Server server = dbSystem.getDatabase()
|
||||
.query(ServerQueries.fetchServerMatchingIdentifier(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));
|
||||
}
|
||||
|
||||
public void onHotswap(CMDSender sender, Arguments arguments) {
|
||||
public void onHotswap(CMDSender sender, @Untrusted Arguments arguments) {
|
||||
DBType toDB = arguments.get(0).flatMap(DBType::getForName)
|
||||
.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);
|
||||
}
|
||||
|
||||
public void onOnlineConversion(String mainCommand, CMDSender sender, Arguments arguments) {
|
||||
public void onOnlineConversion(String mainCommand, CMDSender sender, @Untrusted Arguments arguments) {
|
||||
boolean removeOfflinePlayers = arguments.get(0)
|
||||
.map("--remove_offline"::equals)
|
||||
.orElse(false);
|
||||
@ -491,7 +492,7 @@ public class DatabaseCommands {
|
||||
Map<UUID, BaseUser> baseUsersByUUID = dbSystem.getDatabase().query(BaseUserQueries.fetchAllBaseUsersByUUID());
|
||||
List<String> playerNames = baseUsersByUUID.values().stream().map(BaseUser::getName).collect(Collectors.toList());
|
||||
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);
|
||||
|
||||
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.queries.objects.ServerQueries;
|
||||
import com.djrapitops.plan.storage.database.queries.objects.WebUserQueries;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
@ -92,9 +93,9 @@ public class LinkCommands {
|
||||
* @param sender Sender of command.
|
||||
* @param arguments Given arguments.
|
||||
*/
|
||||
public void onServerCommand(CMDSender sender, Arguments arguments) {
|
||||
public void onServerCommand(CMDSender sender, @Untrusted Arguments arguments) {
|
||||
Server server;
|
||||
String identifier = arguments.concatenate(" ");
|
||||
@Untrusted String identifier = arguments.concatenate(" ");
|
||||
if (arguments.isEmpty()) {
|
||||
server = serverInfo.getServer();
|
||||
} else {
|
||||
@ -117,7 +118,7 @@ public class LinkCommands {
|
||||
* @param sender Sender of command.
|
||||
* @param arguments Given arguments.
|
||||
*/
|
||||
public void onServersCommand(CMDSender sender, Arguments arguments) {
|
||||
public void onServersCommand(CMDSender sender, @Untrusted Arguments arguments) {
|
||||
ensureDatabaseIsOpen();
|
||||
String m = colors.getMainColor();
|
||||
String s = colors.getSecondaryColor();
|
||||
@ -148,8 +149,8 @@ public class LinkCommands {
|
||||
* @param sender Sender of command.
|
||||
* @param arguments Given arguments.
|
||||
*/
|
||||
public void onPlayerCommand(CMDSender sender, Arguments arguments) {
|
||||
String identifier = arguments.concatenate(" ");
|
||||
public void onPlayerCommand(CMDSender sender, @Untrusted Arguments arguments) {
|
||||
@Untrusted String identifier = arguments.concatenate(" ");
|
||||
UUID playerUUID = identifiers.getPlayerUUID(identifier);
|
||||
UUID senderUUID = sender.getUUID().orElse(null);
|
||||
if (playerUUID == null) playerUUID = senderUUID;
|
||||
@ -174,7 +175,7 @@ public class LinkCommands {
|
||||
* @param sender Sender of command
|
||||
* @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";
|
||||
sender.buildMessage()
|
||||
.addPart(colors.getMainColor() + locale.getString(CommandLang.LINK_PLAYERS))
|
||||
@ -188,7 +189,7 @@ public class LinkCommands {
|
||||
* @param sender Sender of command
|
||||
* @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";
|
||||
sender.buildMessage()
|
||||
.addPart(colors.getMainColor() + locale.getString(CommandLang.LINK_NETWORK))
|
||||
@ -205,7 +206,7 @@ public class LinkCommands {
|
||||
* @param sender Sender of command.
|
||||
* @param arguments Given arguments.
|
||||
*/
|
||||
public void onWebUsersCommand(CMDSender sender, Arguments arguments) {
|
||||
public void onWebUsersCommand(CMDSender sender, @Untrusted Arguments arguments) {
|
||||
ensureDatabaseIsOpen();
|
||||
String m = colors.getMainColor();
|
||||
String s = colors.getSecondaryColor();
|
||||
@ -227,8 +228,8 @@ public class LinkCommands {
|
||||
}
|
||||
}
|
||||
|
||||
public void onJson(CMDSender sender, Arguments arguments) {
|
||||
String identifier = arguments.concatenate(" ");
|
||||
public void onJson(CMDSender sender, @Untrusted Arguments arguments) {
|
||||
@Untrusted String identifier = arguments.concatenate(" ");
|
||||
UUID playerUUID = identifiers.getPlayerUUID(identifier);
|
||||
UUID senderUUID = sender.getUUID().orElse(null);
|
||||
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.Database;
|
||||
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.ErrorLogger;
|
||||
import com.djrapitops.plan.version.VersionChecker;
|
||||
@ -33,7 +34,6 @@ import net.playeranalytics.plugin.PluginInformation;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.Optional;
|
||||
|
||||
@Singleton
|
||||
public class PluginStatusCommands {
|
||||
@ -80,15 +80,15 @@ public class PluginStatusCommands {
|
||||
}, "Plan Reload Thread").start();
|
||||
}
|
||||
|
||||
public void onDisable(CMDSender sender, Arguments arguments) {
|
||||
public void onDisable(CMDSender sender, @Untrusted Arguments arguments) {
|
||||
if (arguments.isEmpty()) {
|
||||
plugin.onDisable();
|
||||
sender.send(locale.getString(CommandLang.DISABLE_DISABLED));
|
||||
return;
|
||||
}
|
||||
|
||||
Optional<String> kickCountDisable = arguments.get(0).filter("kickcount"::equalsIgnoreCase);
|
||||
if (kickCountDisable.isPresent()) {
|
||||
boolean kickCountDisable = arguments.get(0).map("kickcount"::equalsIgnoreCase).orElse(false);
|
||||
if (kickCountDisable) {
|
||||
status.setCountKicks(false);
|
||||
sender.send(locale.getString(CommandLang.FEATURE_DISABLED, "Kick Counting"));
|
||||
} 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.StoreWebUserTransaction;
|
||||
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.ErrorLogger;
|
||||
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();
|
||||
if (arguments.isEmpty()) {
|
||||
String address = linkCommands.getAddress(sender) + "/register";
|
||||
@ -96,7 +97,7 @@ public class RegistrationCommands {
|
||||
.apply(builder -> linkCommands.linkTo(builder, sender, address))
|
||||
.send();
|
||||
} else {
|
||||
Optional<String> code = arguments.getAfter("--code");
|
||||
@Untrusted Optional<String> code = arguments.getAfter("--code");
|
||||
if (code.isPresent()) {
|
||||
registerUsingCode(sender, code.get());
|
||||
} 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);
|
||||
Optional<User> user = RegistrationBin.register(code, linkedToUUID);
|
||||
if (user.isPresent()) {
|
||||
@ -115,8 +116,8 @@ public class RegistrationCommands {
|
||||
}
|
||||
}
|
||||
|
||||
public void registerUsingLegacy(CMDSender sender, Arguments arguments) {
|
||||
String password = arguments.get(0)
|
||||
public void registerUsingLegacy(CMDSender sender, @Untrusted Arguments arguments) {
|
||||
@Untrusted String password = arguments.get(0)
|
||||
.orElseThrow(() -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_REQ_ARGS, 1, "<password>")));
|
||||
String passwordHash = PassEncryptUtil.createHash(password);
|
||||
int permissionLevel = arguments.getInteger(2)
|
||||
@ -128,10 +129,10 @@ public class RegistrationCommands {
|
||||
if (senderUUID.isPresent() && senderName.isPresent()) {
|
||||
String playerName = senderName.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);
|
||||
} 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>")));
|
||||
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) {
|
||||
Optional<String> givenUsername = arguments.get(0).filter(arg -> sender.hasPermission(Permissions.UNREGISTER_OTHER));
|
||||
public void onUnregister(String mainCommand, CMDSender sender, @Untrusted Arguments arguments) {
|
||||
@Untrusted Optional<String> givenUsername = arguments.get(0).filter(arg -> sender.hasPermission(Permissions.UNREGISTER_OTHER));
|
||||
|
||||
Database database = dbSystem.getDatabase();
|
||||
UUID playerUUID = sender.getUUID().orElse(null);
|
||||
|
||||
String username;
|
||||
@Untrusted String username;
|
||||
if (givenUsername.isEmpty() && playerUUID != null) {
|
||||
username = database.query(WebUserQueries.fetchUser(playerUUID))
|
||||
.map(User::getUsername)
|
||||
@ -231,8 +232,8 @@ public class RegistrationCommands {
|
||||
}
|
||||
|
||||
|
||||
public void onLogoutCommand(CMDSender sender, Arguments arguments) {
|
||||
String loggingOut = arguments.get(0)
|
||||
public void onLogoutCommand(CMDSender sender, @Untrusted Arguments arguments) {
|
||||
@Untrusted String loggingOut = arguments.get(0)
|
||||
.orElseThrow(() -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_REQ_ONE_ARG, locale.getString(HelpLang.ARG_USERNAME) + "/*")));
|
||||
|
||||
if ("*".equals(loggingOut)) {
|
||||
|
@ -16,6 +16,7 @@
|
||||
*/
|
||||
package com.djrapitops.plan.commands.use;
|
||||
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.text.TextStringBuilder;
|
||||
|
||||
@ -29,6 +30,7 @@ import java.util.Optional;
|
||||
*
|
||||
* @author AuroraLS3
|
||||
*/
|
||||
@Untrusted
|
||||
public class Arguments {
|
||||
|
||||
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.lang.CommandLang;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
import com.djrapitops.plan.utilities.java.TriConsumer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -54,7 +55,7 @@ public class CommandWithSubcommands extends Subcommand {
|
||||
return subcommands;
|
||||
}
|
||||
|
||||
public Optional<Subcommand> findSubCommand(Arguments arguments) {
|
||||
public Optional<Subcommand> findSubCommand(@Untrusted Arguments arguments) {
|
||||
return arguments.get(0).flatMap(alias -> {
|
||||
for (Subcommand subcommand : subcommands) {
|
||||
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);
|
||||
sender.buildMessage()
|
||||
.addPart(locale.getString(CommandLang.HEADER_HELP, getPrimaryAlias()))
|
||||
@ -89,7 +90,7 @@ public class CommandWithSubcommands extends Subcommand {
|
||||
.send();
|
||||
}
|
||||
|
||||
public void onCommand(CMDSender sender, Arguments arguments) {
|
||||
public void onCommand(CMDSender sender, @Untrusted Arguments arguments) {
|
||||
if (sender.isMissingPermissionsFor(this)) {
|
||||
sender.send(locale.getString(CommandLang.FAIL_NO_PERMISSION) + " " + getRequiredPermissions());
|
||||
return;
|
||||
@ -101,10 +102,10 @@ public class CommandWithSubcommands extends Subcommand {
|
||||
}
|
||||
}
|
||||
|
||||
public void executeCommand(CMDSender sender, Arguments arguments) {
|
||||
Optional<String> gotAlias = arguments.get(0);
|
||||
public void executeCommand(CMDSender sender, @Untrusted Arguments arguments) {
|
||||
@Untrusted Optional<String> gotAlias = arguments.get(0);
|
||||
if (gotAlias.isPresent()) {
|
||||
String alias = gotAlias.get();
|
||||
@Untrusted String alias = gotAlias.get();
|
||||
if ("help".equals(alias)) {
|
||||
onHelp(sender, arguments);
|
||||
return;
|
||||
@ -128,8 +129,8 @@ public class CommandWithSubcommands extends Subcommand {
|
||||
fallback.accept(sender, arguments);
|
||||
}
|
||||
|
||||
public List<String> onTabComplete(CMDSender sender, Arguments arguments) {
|
||||
Optional<String> gotAlias = arguments.get(0);
|
||||
public List<String> onTabComplete(CMDSender sender, @Untrusted Arguments arguments) {
|
||||
@Untrusted Optional<String> gotAlias = arguments.get(0);
|
||||
List<String> options = new ArrayList<>();
|
||||
if (gotAlias.isPresent()) {
|
||||
subcommandsLoop:
|
||||
|
@ -17,6 +17,7 @@
|
||||
package com.djrapitops.plan.delivery.domain;
|
||||
|
||||
import com.djrapitops.plan.identification.ServerUUID;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@ -27,6 +28,7 @@ import java.util.Objects;
|
||||
*/
|
||||
public class Nickname implements DateHolder {
|
||||
|
||||
@Untrusted
|
||||
private final String name;
|
||||
private final long date;
|
||||
private final ServerUUID serverUUID;
|
||||
@ -37,6 +39,7 @@ public class Nickname implements DateHolder {
|
||||
this.serverUUID = serverUUID;
|
||||
}
|
||||
|
||||
@Untrusted
|
||||
public String getName() {
|
||||
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.utilities.PassEncryptUtil;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Objects;
|
||||
@ -30,6 +31,7 @@ import java.util.UUID;
|
||||
*/
|
||||
public class User implements Comparable<User> {
|
||||
|
||||
@Untrusted
|
||||
private final String username;
|
||||
private final String linkedTo;
|
||||
private final UUID linkedToUUID; // null for 'console'
|
||||
@ -37,7 +39,7 @@ public class User implements Comparable<User> {
|
||||
private int permissionLevel;
|
||||
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.linkedTo = linkedTo;
|
||||
this.linkedToUUID = linkedToUUID;
|
||||
@ -46,7 +48,7 @@ public class User implements Comparable<User> {
|
||||
this.permissions = permissions;
|
||||
}
|
||||
|
||||
public boolean doesPasswordMatch(String password) {
|
||||
public boolean doesPasswordMatch(@Untrusted String password) {
|
||||
return PassEncryptUtil.verifyPassword(password, passwordHash);
|
||||
}
|
||||
|
||||
@ -54,6 +56,7 @@ public class User implements Comparable<User> {
|
||||
return new WebUser(linkedTo, linkedToUUID, username, permissions);
|
||||
}
|
||||
|
||||
@Untrusted
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
package com.djrapitops.plan.delivery.domain.datatransfer;
|
||||
|
||||
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.reflect.TypeToken;
|
||||
|
||||
@ -28,6 +29,7 @@ import java.util.*;
|
||||
*
|
||||
* @author AuroraLS3
|
||||
*/
|
||||
@Untrusted
|
||||
public class InputFilterDto {
|
||||
|
||||
private final String kind;
|
||||
@ -38,7 +40,7 @@ public class InputFilterDto {
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -16,11 +16,14 @@
|
||||
*/
|
||||
package com.djrapitops.plan.delivery.domain.datatransfer;
|
||||
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class InputQueryDto {
|
||||
|
||||
@Untrusted
|
||||
public final List<InputFilterDto> filters;
|
||||
private final ViewDto view;
|
||||
|
||||
@ -33,6 +36,7 @@ public class InputQueryDto {
|
||||
return view;
|
||||
}
|
||||
|
||||
@Untrusted
|
||||
public List<InputFilterDto> getFilters() {
|
||||
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.Formatters;
|
||||
import com.djrapitops.plan.identification.ServerUUID;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
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.
|
||||
*/
|
||||
@Untrusted
|
||||
public class ViewDto {
|
||||
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.ServerTablePlayersQuery;
|
||||
import com.djrapitops.plan.utilities.comparators.SessionStartComparator;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
import com.djrapitops.plan.utilities.java.Maps;
|
||||
|
||||
import javax.inject.Inject;
|
||||
@ -175,7 +176,7 @@ public class JSONFactory {
|
||||
return new PlayerKillMutator(kills).toJSONAsMap(formatters);
|
||||
}
|
||||
|
||||
public Optional<ServerDto> serverForIdentifier(String identifier) {
|
||||
public Optional<ServerDto> serverForIdentifier(@Untrusted String identifier) {
|
||||
return dbSystem.getDatabase()
|
||||
.query(ServerQueries.fetchServerMatchingIdentifier(identifier))
|
||||
.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.icon.Icon;
|
||||
import com.djrapitops.plan.exceptions.ExceptionWithContext;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
import com.djrapitops.plan.version.VersionChecker;
|
||||
import org.apache.commons.text.StringEscapeUtils;
|
||||
import org.apache.commons.text.TextStringBuilder;
|
||||
|
||||
/**
|
||||
@ -32,7 +34,9 @@ import org.apache.commons.text.TextStringBuilder;
|
||||
public class InternalErrorPage implements Page {
|
||||
|
||||
private final String template;
|
||||
@Untrusted
|
||||
private final String errorMsg;
|
||||
@Untrusted
|
||||
private final Throwable error;
|
||||
|
||||
private final VersionChecker versionChecker;
|
||||
@ -66,13 +70,13 @@ public class InternalErrorPage implements Page {
|
||||
paragraph.append("Please report this issue here: ");
|
||||
paragraph.append(Html.LINK.create("https://github.com/plan-player-analytics/Plan/issues", "Issues"));
|
||||
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) {
|
||||
((ExceptionWithContext) error).getContext()
|
||||
.ifPresent(context -> paragraph.append(context.getWhatToDo()
|
||||
.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>")
|
||||
.appendWithSeparators(context.toLines(), "<br>")
|
||||
.append("<br>"));
|
||||
@ -91,8 +95,8 @@ public class InternalErrorPage implements Page {
|
||||
return paragraph.toString();
|
||||
}
|
||||
|
||||
private void appendCause(Throwable cause, TextStringBuilder paragraph) {
|
||||
paragraph.append("<br>Caused by: ").append(cause);
|
||||
private void appendCause(@Untrusted Throwable cause, TextStringBuilder paragraph) {
|
||||
paragraph.append("<br>Caused by: ").append(StringEscapeUtils.escapeHtml4(cause.toString()));
|
||||
for (StackTraceElement element : cause.getStackTrace()) {
|
||||
paragraph.append("<br>");
|
||||
paragraph.append(" ").append(element);
|
||||
|
@ -17,6 +17,7 @@
|
||||
package com.djrapitops.plan.delivery.web;
|
||||
|
||||
import com.djrapitops.plan.delivery.web.resolver.Resolver;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
@ -69,7 +70,7 @@ public class ResolverSvc implements ResolverService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Resolver> getResolvers(String target) {
|
||||
public List<Resolver> getResolvers(@Untrusted String target) {
|
||||
List<Resolver> resolvers = new ArrayList<>();
|
||||
for (Container container : basicResolvers) {
|
||||
if (container.matcher.test(target)) resolvers.add(container.resolver);
|
||||
|
@ -16,6 +16,7 @@
|
||||
*/
|
||||
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.Caffeine;
|
||||
|
||||
@ -33,7 +34,7 @@ public class PassBruteForceGuard {
|
||||
.expireAfterWrite(90, TimeUnit.SECONDS)
|
||||
.build();
|
||||
|
||||
public boolean shouldPreventRequest(String accessor) {
|
||||
public boolean shouldPreventRequest(@Untrusted String accessor) {
|
||||
Integer attempts = failedLoginAttempts.getIfPresent(accessor);
|
||||
if (attempts == null) return false;
|
||||
// Too many attempts, forbid further attempts.
|
||||
@ -41,7 +42,7 @@ public class PassBruteForceGuard {
|
||||
}
|
||||
|
||||
// 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
|
||||
failedLoginAttempts.cleanUp();
|
||||
|
||||
@ -59,7 +60,7 @@ public class PassBruteForceGuard {
|
||||
failedLoginAttempts.put(accessor, attempts + 1);
|
||||
}
|
||||
|
||||
public void resetAttemptCount(String accessor) {
|
||||
public void resetAttemptCount(@Untrusted String accessor) {
|
||||
// Successful login
|
||||
failedLoginAttempts.cleanUp();
|
||||
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.URIQuery;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
@ -38,7 +39,7 @@ public class RequestBodyConverter {
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -36,10 +36,12 @@ import com.djrapitops.plan.storage.database.DBSystem;
|
||||
import com.djrapitops.plan.storage.database.Database;
|
||||
import com.djrapitops.plan.storage.database.queries.containers.ContainerFetchQueries;
|
||||
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.UnaryChain;
|
||||
import dagger.Lazy;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.text.StringEscapeUtils;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
@ -375,11 +377,11 @@ public class ResponseFactory {
|
||||
.build();
|
||||
}
|
||||
|
||||
public Response ipWhitelist403(String accessor) {
|
||||
public Response ipWhitelist403(@Untrusted String accessor) {
|
||||
return Response.builder()
|
||||
.setMimeType(MimeType.HTML)
|
||||
.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)
|
||||
.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.exceptions.WebUserAuthException;
|
||||
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.ErrorLogger;
|
||||
import dagger.Lazy;
|
||||
@ -167,7 +168,7 @@ public class ResponseResolver {
|
||||
return request -> Optional.of(response.get());
|
||||
}
|
||||
|
||||
public Response getResponse(Request request) {
|
||||
public Response getResponse(@Untrusted Request request) {
|
||||
try {
|
||||
return tryToGetResponse(request);
|
||||
} catch (NotFoundException e) {
|
||||
@ -189,7 +190,7 @@ public class ResponseResolver {
|
||||
* @throws ForbiddenException If the user is not allowed to see the page
|
||||
* @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())) {
|
||||
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/OPTIONS
|
||||
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.queries.objects.WebUserQueries;
|
||||
import com.djrapitops.plan.storage.database.transactions.events.CookieChangeTransaction;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
import net.playeranalytics.plugin.server.PluginLogger;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
|
||||
@ -70,7 +71,7 @@ public class ActiveCookieStore implements SubSystem {
|
||||
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))
|
||||
.findAny()
|
||||
.map(Map.Entry::getKey)
|
||||
@ -106,7 +107,7 @@ public class ActiveCookieStore implements SubSystem {
|
||||
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));
|
||||
}
|
||||
|
||||
@ -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)
|
||||
.ifPresent(this::deleteCookieByUser);
|
||||
USERS_BY_COOKIE.remove(cookie);
|
||||
deleteCookie(cookie);
|
||||
}
|
||||
|
||||
private void deleteCookie(String cookie) {
|
||||
private void deleteCookie(@Untrusted String 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.paths.WebserverSettings;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
@ -44,7 +45,7 @@ public class AllowedIpList {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isAllowed(String accessAddress) {
|
||||
public boolean isAllowed(@Untrusted String accessAddress) {
|
||||
prepare();
|
||||
|
||||
List<String> ips = allowList.get();
|
||||
|
@ -17,6 +17,7 @@
|
||||
package com.djrapitops.plan.delivery.webserver.auth;
|
||||
|
||||
import com.djrapitops.plan.delivery.webserver.http.InternalRequest;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
@ -37,8 +38,8 @@ public class AuthenticationExtractor {
|
||||
return getCookieAuthentication(internalRequest.getCookies());
|
||||
}
|
||||
|
||||
private Optional<Authentication> getCookieAuthentication(List<Cookie> cookies) {
|
||||
for (Cookie cookie : cookies) {
|
||||
private Optional<Authentication> getCookieAuthentication(@Untrusted List<Cookie> cookies) {
|
||||
for (@Untrusted Cookie cookie : cookies) {
|
||||
if ("auth".equals(cookie.getName())) {
|
||||
return Optional.of(new CookieAuthentication(activeCookieStore, cookie.getValue()));
|
||||
}
|
||||
|
@ -16,8 +16,10 @@
|
||||
*/
|
||||
package com.djrapitops.plan.delivery.webserver.auth;
|
||||
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
@Untrusted
|
||||
public class Cookie {
|
||||
|
||||
private final String name;
|
||||
|
@ -17,13 +17,15 @@
|
||||
package com.djrapitops.plan.delivery.webserver.auth;
|
||||
|
||||
import com.djrapitops.plan.delivery.domain.auth.User;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
|
||||
public class CookieAuthentication implements Authentication {
|
||||
|
||||
private final ActiveCookieStore activeCookieStore;
|
||||
@Untrusted
|
||||
private final String cookie;
|
||||
|
||||
public CookieAuthentication(ActiveCookieStore activeCookieStore, String cookie) {
|
||||
public CookieAuthentication(ActiveCookieStore activeCookieStore, @Untrusted String cookie) {
|
||||
this.activeCookieStore = activeCookieStore;
|
||||
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.utilities.PassEncryptUtil;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
import com.github.benmanes.caffeine.cache.Cache;
|
||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
@ -42,29 +43,30 @@ public class RegistrationBin {
|
||||
// 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 code = DigestUtils.sha256Hex(username + password + System.currentTimeMillis()).substring(0, 12);
|
||||
REGISTRATION_BIN.put(code, new AwaitingForRegistration(username, hash));
|
||||
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);
|
||||
if (found == null) return Optional.empty();
|
||||
REGISTRATION_BIN.invalidate(code);
|
||||
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;
|
||||
}
|
||||
|
||||
private static class AwaitingForRegistration {
|
||||
@Untrusted
|
||||
private final String username;
|
||||
private final String passwordHash;
|
||||
|
||||
public AwaitingForRegistration(String username, String passwordHash) {
|
||||
public AwaitingForRegistration(@Untrusted String username, String passwordHash) {
|
||||
this.username = username;
|
||||
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.locale.Locale;
|
||||
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.ErrorLogger;
|
||||
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));
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,7 @@ import com.djrapitops.plan.delivery.webserver.configuration.WebserverConfigurati
|
||||
import com.djrapitops.plan.exceptions.database.DBOpException;
|
||||
import com.djrapitops.plan.storage.database.DBSystem;
|
||||
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.ErrorLogger;
|
||||
import net.playeranalytics.plugin.server.PluginLogger;
|
||||
@ -46,10 +47,10 @@ public class AccessLogger {
|
||||
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()) {
|
||||
int code = response.getCode();
|
||||
String message = "Access Log: " + internalRequest.getMethod() + " " +
|
||||
@Untrusted String message = "Access Log: " + internalRequest.getMethod() + " " +
|
||||
getRequestURI(internalRequest, request) +
|
||||
" (from " + internalRequest.getAccessAddress(webserverConfiguration) + ") - " +
|
||||
code;
|
||||
@ -82,6 +83,7 @@ public class AccessLogger {
|
||||
}
|
||||
}
|
||||
|
||||
@Untrusted
|
||||
private String getRequestURI(InternalRequest internalRequest, Request request) {
|
||||
return request != null ? request.getPath().asString() + request.getQuery().asString()
|
||||
: 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.Cookie;
|
||||
import com.djrapitops.plan.delivery.webserver.configuration.WebserverConfiguration;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
@ -36,10 +37,11 @@ public interface InternalRequest {
|
||||
|
||||
long getTimestamp();
|
||||
|
||||
@Untrusted
|
||||
default String getAccessAddress(WebserverConfiguration webserverConfiguration) {
|
||||
AccessAddressPolicy accessAddressPolicy = webserverConfiguration.getAccessAddressPolicy();
|
||||
if (accessAddressPolicy == AccessAddressPolicy.X_FORWARDED_FOR_HEADER) {
|
||||
String fromHeader = getAccessAddressFromHeader();
|
||||
@Untrusted String fromHeader = getAccessAddressFromHeader();
|
||||
if (fromHeader == null) {
|
||||
webserverConfiguration.getWebserverLogMessages().warnAboutXForwardedForSecurityIssue();
|
||||
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.Cookie;
|
||||
import com.djrapitops.plan.delivery.webserver.configuration.WebserverConfiguration;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.apache.commons.text.TextStringBuilder;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
@ -72,11 +73,11 @@ public class JettyInternalRequest implements InternalRequest {
|
||||
@Override
|
||||
public com.djrapitops.plan.delivery.web.resolver.request.Request toRequest() {
|
||||
String requestMethod = baseRequest.getMethod();
|
||||
URIPath path = new URIPath(baseRequest.getHttpURI().getDecodedPath());
|
||||
URIQuery query = new URIQuery(baseRequest.getHttpURI().getQuery());
|
||||
byte[] requestBody = readRequestBody();
|
||||
@Untrusted URIPath path = new URIPath(baseRequest.getHttpURI().getDecodedPath());
|
||||
@Untrusted URIQuery query = new URIQuery(baseRequest.getHttpURI().getQuery());
|
||||
@Untrusted byte[] requestBody = readRequestBody();
|
||||
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);
|
||||
}
|
||||
|
||||
@ -106,7 +107,7 @@ public class JettyInternalRequest implements InternalRequest {
|
||||
|
||||
@Override
|
||||
public List<Cookie> getCookies() {
|
||||
List<String> textCookies = getCookieHeaders();
|
||||
@Untrusted List<String> textCookies = getCookieHeaders();
|
||||
List<Cookie> cookies = new ArrayList<>();
|
||||
if (!textCookies.isEmpty()) {
|
||||
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.configuration.WebserverConfiguration;
|
||||
import com.djrapitops.plan.exceptions.WebUserAuthException;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
|
||||
@ -52,10 +53,10 @@ public class RequestHandler {
|
||||
}
|
||||
|
||||
public Response getResponse(InternalRequest internalRequest) {
|
||||
String accessAddress = internalRequest.getAccessAddress(webserverConfiguration);
|
||||
@Untrusted String accessAddress = internalRequest.getAccessAddress(webserverConfiguration);
|
||||
|
||||
Response response;
|
||||
Request request = null;
|
||||
@Untrusted Request request = null;
|
||||
if (bruteForceGuard.shouldPreventRequest(accessAddress)) {
|
||||
response = responseFactory.failedLoginAttempts403();
|
||||
} else if (!webserverConfiguration.getAllowedIpList().isAllowed(accessAddress)) {
|
||||
@ -81,17 +82,17 @@ public class RequestHandler {
|
||||
return response;
|
||||
}
|
||||
|
||||
private Response attemptToResolve(Request request, String accessAddress) {
|
||||
private Response attemptToResolve(@Untrusted Request request, @Untrusted String accessAddress) {
|
||||
Response response = protocolUpgradeResponse(request)
|
||||
.orElseGet(() -> responseResolver.getResponse(request));
|
||||
request.getUser().ifPresent(user -> processSuccessfulLogin(response.getCode(), accessAddress));
|
||||
return response;
|
||||
}
|
||||
|
||||
private Optional<Response> protocolUpgradeResponse(Request request) {
|
||||
Optional<String> upgrade = request.getHeader(HttpHeader.UPGRADE.asString());
|
||||
private Optional<Response> protocolUpgradeResponse(@Untrusted Request request) {
|
||||
@Untrusted Optional<String> upgrade = request.getHeader(HttpHeader.UPGRADE.asString());
|
||||
if (upgrade.isPresent()) {
|
||||
String value = upgrade.get();
|
||||
@Untrusted String value = upgrade.get();
|
||||
if ("h2c".equals(value) || "h2".equals(value)) {
|
||||
return Optional.of(Response.builder()
|
||||
.setStatus(101)
|
||||
@ -103,12 +104,12 @@ public class RequestHandler {
|
||||
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();
|
||||
if (failReason == FailReason.USER_PASS_MISMATCH) {
|
||||
return processWrongPassword(accessAddress, failReason);
|
||||
} else {
|
||||
String from = internalRequest.getRequestedURIString();
|
||||
@Untrusted String from = internalRequest.getRequestedURIString();
|
||||
String directTo = StringUtils.startsWithAny(from, "/auth/", "/login") ? "/login" : "/login?from=." + from;
|
||||
return Response.builder()
|
||||
.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);
|
||||
if (bruteForceGuard.shouldPreventRequest(accessAddress)) {
|
||||
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 notForbidden = responseCode != 403;
|
||||
if (successfulLogin && notForbidden) {
|
||||
|
@ -26,7 +26,9 @@ import com.djrapitops.plan.delivery.webserver.ResponseFactory;
|
||||
import com.djrapitops.plan.identification.UUIDUtility;
|
||||
import com.djrapitops.plan.settings.config.PlanConfig;
|
||||
import com.djrapitops.plan.settings.config.paths.PluginSettings;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
@ -60,17 +62,22 @@ public class PlayerPageResolver implements Resolver {
|
||||
public boolean canAccess(Request request) {
|
||||
URIPath path = request.getPath();
|
||||
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
|
||||
return uuidUtility.getNameOf(nameOrUUID).map(user.getName()::equalsIgnoreCase) // uuid matches user
|
||||
.orElse(false); // uuid or name don't match
|
||||
}).orElse(true); // No name or UUID given
|
||||
return user.hasPermission("page.player.other") || user.hasPermission("page.player.self") && isOwnPage;
|
||||
}
|
||||
|
||||
@Override
|
||||
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/")) {
|
||||
return Optional.empty();
|
||||
}
|
||||
@ -78,7 +85,7 @@ public class PlayerPageResolver implements Resolver {
|
||||
.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);
|
||||
if (playerUUID == null) return responseFactory.uuidNotFound404();
|
||||
|
||||
|
@ -32,6 +32,7 @@ import dagger.Lazy;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Resolves '/' URL (Address Root).
|
||||
@ -72,7 +73,7 @@ public class RootPageResolver implements NoAuthResolver {
|
||||
} else if (user.hasPermission("page.players")) {
|
||||
return responseFactory.redirectResponse("players");
|
||||
} 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 {
|
||||
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.storage.database.DBSystem;
|
||||
import com.djrapitops.plan.storage.database.queries.objects.ServerQueries;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
@ -58,7 +59,7 @@ public class ServerPageResolver implements Resolver {
|
||||
|
||||
@Override
|
||||
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(""));
|
||||
boolean forServerPage = "server".equalsIgnoreCase(firstPart) && permissions.hasPermission("page.server");
|
||||
boolean forNetworkPage = "network".equalsIgnoreCase(firstPart) && permissions.hasPermission("page.network");
|
||||
@ -92,7 +93,7 @@ public class ServerPageResolver implements Resolver {
|
||||
return Optional.of(responseFactory.serverPageResponse(serverUUID));
|
||||
}
|
||||
|
||||
private Optional<ServerUUID> getServerUUID(URIPath path) {
|
||||
private Optional<ServerUUID> getServerUUID(@Untrusted URIPath path) {
|
||||
if (serverInfo.getServer().isProxy()
|
||||
&& 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.URIPath;
|
||||
import com.djrapitops.plan.delivery.webserver.ResponseFactory;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import javax.inject.Inject;
|
||||
@ -51,7 +52,7 @@ public class StaticResourceResolver implements NoAuthResolver {
|
||||
}
|
||||
|
||||
private Response getResponse(Request request) {
|
||||
String resource = getPath(request).asString().substring(1);
|
||||
@Untrusted String resource = getPath(request).asString().substring(1);
|
||||
if (resource.endsWith(".css")) {
|
||||
return responseFactory.cssResponse(resource);
|
||||
}
|
||||
@ -68,7 +69,7 @@ public class StaticResourceResolver implements NoAuthResolver {
|
||||
}
|
||||
|
||||
private URIPath getPath(Request request) {
|
||||
URIPath path = request.getPath();
|
||||
@Untrusted URIPath path = request.getPath();
|
||||
// Remove everything before /vendor /css /js or /img
|
||||
while (!path.getPart(0).map(part -> part.matches(PART_REGEX)).orElse(true)) {
|
||||
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.webserver.ResponseFactory;
|
||||
import com.djrapitops.plan.delivery.webserver.http.WebServer;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
import dagger.Lazy;
|
||||
|
||||
import javax.inject.Inject;
|
||||
@ -44,10 +45,10 @@ public class LoginPageResolver implements NoAuthResolver {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Response> resolve(Request request) {
|
||||
public Optional<Response> resolve(@Untrusted Request request) {
|
||||
Optional<WebUser> user = request.getUser();
|
||||
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"));
|
||||
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.storage.database.DBSystem;
|
||||
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.media.Content;
|
||||
import io.swagger.v3.oas.annotations.media.ExampleObject;
|
||||
@ -92,11 +93,11 @@ public class LoginResolver implements NoAuthResolver {
|
||||
.build();
|
||||
}
|
||||
|
||||
public User getUser(Request request) {
|
||||
URIQuery form = RequestBodyConverter.formBody(request);
|
||||
URIQuery query = request.getQuery();
|
||||
String username = getUser(form, query);
|
||||
String password = getPassword(form, query);
|
||||
public User getUser(@Untrusted Request request) {
|
||||
@Untrusted URIQuery form = RequestBodyConverter.formBody(request);
|
||||
@Untrusted URIQuery query = request.getQuery();
|
||||
@Untrusted String username = getUser(form, query);
|
||||
@Untrusted String password = getPassword(form, query);
|
||||
User user = dbSystem.getDatabase().query(WebUserQueries.fetchUser(username))
|
||||
.orElseThrow(() -> new WebUserAuthException(FailReason.USER_PASS_MISMATCH));
|
||||
|
||||
@ -107,13 +108,13 @@ public class LoginResolver implements NoAuthResolver {
|
||||
return user;
|
||||
}
|
||||
|
||||
private String getPassword(URIQuery form, URIQuery query) {
|
||||
private String getPassword(@Untrusted URIQuery form, @Untrusted URIQuery query) {
|
||||
return form.get("password")
|
||||
.orElseGet(() -> query.get("password")
|
||||
.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")
|
||||
.orElseGet(() -> query.get("user")
|
||||
.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.FailReason;
|
||||
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.media.Content;
|
||||
import io.swagger.v3.oas.annotations.media.ExampleObject;
|
||||
@ -57,13 +58,13 @@ public class LogoutResolver implements NoAuthResolver {
|
||||
requestBody = @RequestBody(content = @Content(examples = @ExampleObject()))
|
||||
)
|
||||
@Override
|
||||
public Optional<Response> resolve(Request request) {
|
||||
String cookies = request.getHeader("Cookie").orElse("");
|
||||
String foundCookie = null;
|
||||
for (String cookie : cookies.split(";")) {
|
||||
public Optional<Response> resolve(@Untrusted Request request) {
|
||||
@Untrusted String cookies = request.getHeader("Cookie").orElse("");
|
||||
@Untrusted String foundCookie = null;
|
||||
for (@Untrusted String cookie : cookies.split(";")) {
|
||||
if (cookie.isEmpty()) continue;
|
||||
String[] split = cookie.split("=");
|
||||
String name = split[0];
|
||||
@Untrusted String[] split = cookie.split("=");
|
||||
@Untrusted String name = split[0];
|
||||
if ("auth".equals(name) && split.length > 1) {
|
||||
foundCookie = split[1];
|
||||
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.webserver.ResponseFactory;
|
||||
import com.djrapitops.plan.delivery.webserver.http.WebServer;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
import dagger.Lazy;
|
||||
|
||||
import javax.inject.Inject;
|
||||
@ -44,7 +45,7 @@ public class RegisterPageResolver implements NoAuthResolver {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Response> resolve(Request request) {
|
||||
public Optional<Response> resolve(@Untrusted Request request) {
|
||||
Optional<WebUser> user = request.getUser();
|
||||
if (user.isPresent() || !webServer.get().isAuthRequired()) {
|
||||
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.queries.objects.WebUserQueries;
|
||||
import com.djrapitops.plan.utilities.PassEncryptUtil;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
import com.djrapitops.plan.utilities.java.Maps;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
@ -79,8 +80,8 @@ public class RegisterResolver implements NoAuthResolver {
|
||||
}
|
||||
|
||||
public Response getResponse(Request request) {
|
||||
URIQuery query = request.getQuery();
|
||||
Optional<String> checkCode = query.get("code");
|
||||
@Untrusted URIQuery query = request.getQuery();
|
||||
@Untrusted Optional<String> checkCode = query.get("code");
|
||||
if (checkCode.isPresent()) {
|
||||
return Response.builder()
|
||||
.setStatus(200)
|
||||
@ -88,13 +89,13 @@ public class RegisterResolver implements NoAuthResolver {
|
||||
.build();
|
||||
}
|
||||
|
||||
URIQuery form = RequestBodyConverter.formBody(request);
|
||||
String username = getUser(form, query);
|
||||
@Untrusted URIQuery form = RequestBodyConverter.formBody(request);
|
||||
@Untrusted String username = getUser(form, query);
|
||||
|
||||
boolean alreadyExists = dbSystem.getDatabase().query(WebUserQueries.fetchUser(username)).isPresent();
|
||||
if (alreadyExists) throw new BadRequestException("User already exists!");
|
||||
|
||||
String password = getPassword(form, query);
|
||||
@Untrusted String password = getPassword(form, query);
|
||||
try {
|
||||
String code = RegistrationBin.addInfoForRegistration(username, password);
|
||||
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")
|
||||
.orElseGet(() -> query.get("password")
|
||||
.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")
|
||||
.orElseGet(() -> query.get("user")
|
||||
.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.ServerUUID;
|
||||
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.Parameter;
|
||||
import io.swagger.v3.oas.annotations.enums.ParameterIn;
|
||||
@ -88,14 +89,14 @@ public class ExtensionJSONResolver implements Resolver {
|
||||
)
|
||||
@Override
|
||||
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"));
|
||||
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));
|
||||
}
|
||||
|
||||
private JSONStorage.StoredJSON getJSON(Request request, ServerUUID serverUUID) {
|
||||
private JSONStorage.StoredJSON getJSON(@Untrusted Request request, ServerUUID serverUUID) {
|
||||
Optional<Long> timestamp = Identifiers.getTimestamp(request);
|
||||
|
||||
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.identification.Identifiers;
|
||||
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.Parameter;
|
||||
import io.swagger.v3.oas.annotations.enums.ParameterIn;
|
||||
@ -41,7 +42,6 @@ import jakarta.ws.rs.Path;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.Collections;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
@ -121,7 +121,7 @@ public class GraphsJSONResolver implements Resolver {
|
||||
}
|
||||
|
||||
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."));
|
||||
|
||||
DataID dataID = getDataID(type);
|
||||
@ -132,7 +132,7 @@ public class GraphsJSONResolver implements Resolver {
|
||||
.build();
|
||||
}
|
||||
|
||||
private JSONStorage.StoredJSON getGraphJSON(Request request, DataID dataID) {
|
||||
private JSONStorage.StoredJSON getGraphJSON(@Untrusted Request request, DataID dataID) {
|
||||
Optional<Long> timestamp = Identifiers.getTimestamp(request);
|
||||
|
||||
JSONStorage.StoredJSON storedJSON;
|
||||
@ -151,7 +151,7 @@ public class GraphsJSONResolver implements Resolver {
|
||||
return storedJSON;
|
||||
}
|
||||
|
||||
private DataID getDataID(String type) {
|
||||
private DataID getDataID(@Untrusted String type) {
|
||||
switch (type) {
|
||||
case "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) {
|
||||
case GRAPH_PERFORMANCE:
|
||||
return graphJSON.performanceGraphJSON(serverUUID);
|
||||
@ -218,15 +218,15 @@ public class GraphsJSONResolver implements Resolver {
|
||||
query.get("after").map(Long::parseLong).orElse(0L),
|
||||
query.get("before").map(Long::parseLong).orElse(System.currentTimeMillis())
|
||||
);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new BadRequestException("'after' or 'before' is not a epoch millisecond (number) " + e.getMessage());
|
||||
} catch (@Untrusted NumberFormatException e) {
|
||||
throw new BadRequestException("'after' or 'before' is not a epoch millisecond (number)");
|
||||
}
|
||||
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) {
|
||||
case GRAPH_ACTIVITY:
|
||||
return graphJSON.activityGraphsJSONAsMap();
|
||||
@ -246,11 +246,11 @@ public class GraphsJSONResolver implements Resolver {
|
||||
query.get("after").map(Long::parseLong).orElse(0L),
|
||||
query.get("before").map(Long::parseLong).orElse(System.currentTimeMillis())
|
||||
);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new BadRequestException("'after' or 'before' is not a epoch millisecond (number) " + e.getMessage());
|
||||
} catch (@Untrusted NumberFormatException e) {
|
||||
throw new BadRequestException("'after' or 'before' is not a epoch millisecond (number)");
|
||||
}
|
||||
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.storage.file.PlanFiles;
|
||||
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.Parameter;
|
||||
import io.swagger.v3.oas.annotations.enums.ParameterIn;
|
||||
@ -96,7 +97,7 @@ public class LocaleJSONResolver implements NoAuthResolver {
|
||||
private Response getResponse(Request request) {
|
||||
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(this::getLocaleJSON)
|
||||
.orElseGet(this::getLanguageListJSON);
|
||||
@ -137,7 +138,7 @@ public class LocaleJSONResolver implements NoAuthResolver {
|
||||
return json;
|
||||
}
|
||||
|
||||
private Map<String, Object> getLocaleJSON(String langCode) {
|
||||
private Map<String, Object> getLocaleJSON(@Untrusted String langCode) {
|
||||
try {
|
||||
LangCode code = LangCode.valueOf(langCode.toUpperCase());
|
||||
Map<String, Object> json = new TreeMap<>();
|
||||
@ -153,7 +154,7 @@ public class LocaleJSONResolver implements NoAuthResolver {
|
||||
}
|
||||
|
||||
return dfs(loadLocale(file), json);
|
||||
} catch (IllegalArgumentException noSuchEnum) {
|
||||
} catch (@Untrusted IllegalArgumentException noSuchEnum) {
|
||||
return Collections.emptyMap();
|
||||
} catch (IOException 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.Database;
|
||||
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.reflect.TypeToken;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
@ -119,7 +120,7 @@ public class NetworkPerformanceJSONResolver implements Resolver {
|
||||
.build());
|
||||
}
|
||||
|
||||
private List<UUID> getUUIDList(String jsonString) {
|
||||
private List<UUID> getUUIDList(@Untrusted String jsonString) {
|
||||
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.identification.Identifiers;
|
||||
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.Parameter;
|
||||
import io.swagger.v3.oas.annotations.enums.ParameterIn;
|
||||
@ -100,7 +101,7 @@ public class PlayersTableJSONResolver implements Resolver {
|
||||
.build();
|
||||
}
|
||||
|
||||
private JSONStorage.StoredJSON getStoredJSON(Request request) {
|
||||
private JSONStorage.StoredJSON getStoredJSON(@Untrusted Request request) {
|
||||
Optional<Long> timestamp = Identifiers.getTimestamp(request);
|
||||
JSONStorage.StoredJSON storedJSON;
|
||||
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.SessionQueries;
|
||||
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.google.gson.Gson;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
@ -131,12 +132,12 @@ public class QueryJSONResolver implements Resolver {
|
||||
return Optional.of(getResponse(request));
|
||||
}
|
||||
|
||||
private Response getResponse(Request request) {
|
||||
private Response getResponse(@Untrusted Request request) {
|
||||
Optional<Response> cachedResult = checkForCachedResult(request);
|
||||
if (cachedResult.isPresent()) return cachedResult.get();
|
||||
|
||||
InputQueryDto inputQuery = parseInputQuery(request);
|
||||
List<InputFilterDto> queries = inputQuery.getFilters();
|
||||
@Untrusted List<InputFilterDto> queries = inputQuery.getFilters();
|
||||
|
||||
Filter.Result result = filters.apply(queries);
|
||||
List<Filter.ResultPath> resultPath = result.getInverseResultPath();
|
||||
@ -145,7 +146,7 @@ public class QueryJSONResolver implements Resolver {
|
||||
return buildAndStoreResponse(inputQuery, result, resultPath);
|
||||
}
|
||||
|
||||
private InputQueryDto parseInputQuery(Request request) {
|
||||
private InputQueryDto parseInputQuery(@Untrusted Request request) {
|
||||
if (request.getRequestBody().length == 0) {
|
||||
return parseInputQueryFromQueryParams(request);
|
||||
} else {
|
||||
@ -153,11 +154,11 @@ public class QueryJSONResolver implements Resolver {
|
||||
}
|
||||
}
|
||||
|
||||
private InputQueryDto parseInputQueryFromQueryParams(Request request) {
|
||||
String q = request.getQuery().get("q").orElseThrow(() -> new BadRequestException("'q' parameter not set (expecting json array)"));
|
||||
private InputQueryDto parseInputQueryFromQueryParams(@Untrusted Request request) {
|
||||
@Untrusted String q = request.getQuery().get("q").orElseThrow(() -> new BadRequestException("'q' parameter not set (expecting json array)"));
|
||||
try {
|
||||
String query = URLDecoder.decode(q, StandardCharsets.UTF_8);
|
||||
List<InputFilterDto> queryFilters = InputFilterDto.parse(query, gson);
|
||||
@Untrusted String query = URLDecoder.decode(q, StandardCharsets.UTF_8);
|
||||
@Untrusted List<InputFilterDto> queryFilters = InputFilterDto.parse(query, gson);
|
||||
ViewDto view = request.getQuery().get("view")
|
||||
.map(viewJson -> gson.fromJson(viewJson, ViewDto.class))
|
||||
.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 {
|
||||
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()
|
||||
.setMimeType(MimeType.JSON)
|
||||
.setJSONContent(results.json)
|
||||
.build());
|
||||
} catch (NumberFormatException e) {
|
||||
} catch (@Untrusted NumberFormatException e) {
|
||||
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) {
|
||||
try {
|
||||
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("view", input.getView())
|
||||
.put("filters", input.getFilters())
|
||||
.put("filters", input.getFilters()) // filters json may contain untrusted data
|
||||
.put("timestamp", timestamp)
|
||||
.build();
|
||||
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.NotFoundException;
|
||||
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.Parameter;
|
||||
import io.swagger.v3.oas.annotations.enums.ParameterIn;
|
||||
@ -75,7 +76,7 @@ public class ServerIdentityJSONResolver implements Resolver {
|
||||
)
|
||||
@Override
|
||||
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"));
|
||||
ServerDto server = jsonFactory.serverForIdentifier(serverIdentifier)
|
||||
.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.identification.Identifiers;
|
||||
import com.djrapitops.plan.identification.ServerUUID;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
@ -62,7 +63,7 @@ public class ServerTabJSONResolver<T> implements Resolver {
|
||||
return Optional.of(getResponse(request));
|
||||
}
|
||||
|
||||
private Response getResponse(Request request) {
|
||||
private Response getResponse(@Untrusted Request request) {
|
||||
ServerUUID serverUUID = identifiers.getServerUUID(request); // Can throw BadRequestException
|
||||
return Response.builder()
|
||||
.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.identification.Identifiers;
|
||||
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.Parameter;
|
||||
import io.swagger.v3.oas.annotations.enums.ParameterIn;
|
||||
@ -97,7 +98,7 @@ public class SessionsJSONResolver implements Resolver {
|
||||
.build();
|
||||
}
|
||||
|
||||
private JSONStorage.StoredJSON getStoredJSON(Request request) {
|
||||
private JSONStorage.StoredJSON getStoredJSON(@Untrusted Request request) {
|
||||
Optional<Long> timestamp = Identifiers.getTimestamp(request);
|
||||
if (request.getQuery().get("server").isPresent()) {
|
||||
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.ExtensionProviderTable;
|
||||
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.ResultSet;
|
||||
@ -38,9 +38,10 @@ public class ExtensionUserIdsInGroupQuery extends QueryStatement<Set<Integer>> {
|
||||
private final String pluginName;
|
||||
private final String groupProvider;
|
||||
private final ServerUUID serverUUID;
|
||||
@Untrusted
|
||||
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);
|
||||
this.pluginName = pluginName;
|
||||
this.groupProvider = groupProvider;
|
||||
@ -48,21 +49,19 @@ public class ExtensionUserIdsInGroupQuery extends QueryStatement<Set<Integer>> {
|
||||
this.inGroups = inGroups;
|
||||
}
|
||||
|
||||
private static String buildSQL(Collection<String> inGroups) {
|
||||
TextStringBuilder dynamicInClauseAllocation = new TextStringBuilder();
|
||||
dynamicInClauseAllocation.appendWithSeparators(inGroups.stream().map(group -> "?").toArray(), ",");
|
||||
private static String buildSQL(@Untrusted Collection<String> inGroups) {
|
||||
return SELECT + DISTINCT + "u." + UsersTable.ID +
|
||||
FROM + ExtensionGroupsTable.TABLE_NAME + " groups" +
|
||||
INNER_JOIN + UsersTable.TABLE_NAME + " u on u." + UsersTable.USER_UUID + "=groups." + ExtensionGroupsTable.USER_UUID +
|
||||
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
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
ExtensionProviderTable.set3PluginValuesToStatement(statement, 1, groupProvider, pluginName, serverUUID);
|
||||
int index = 4;
|
||||
for (String group : inGroups) {
|
||||
for (@Untrusted String group : inGroups) {
|
||||
setStringOrNull(statement, index, group == null || "null".equalsIgnoreCase(group) ? null : group);
|
||||
index++;
|
||||
}
|
||||
|
@ -196,6 +196,7 @@ public class FinishedSession implements DateHolder {
|
||||
getExtraData(PlayerKills.class).orElseGet(PlayerKills::new).toJson() + ';' +
|
||||
getExtraData(MobKillCounter.class).orElseGet(MobKillCounter::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(PlayerName.class).map(PlayerName::get).orElseGet(playerUUID::toString);
|
||||
}
|
||||
|
@ -17,11 +17,13 @@
|
||||
package com.djrapitops.plan.gathering.domain.event;
|
||||
|
||||
import com.djrapitops.plan.storage.database.sql.tables.JoinAddressTable;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@Untrusted
|
||||
public class JoinAddress {
|
||||
private final Supplier<String> address;
|
||||
|
||||
@ -33,6 +35,7 @@ public class JoinAddress {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
@Untrusted
|
||||
public String getAddress() {
|
||||
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.gathering.importing.importers.Importer;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
@ -53,7 +54,7 @@ public class ImportSystem implements SubSystem {
|
||||
importers.put(importer.getName(), importer);
|
||||
}
|
||||
|
||||
public Optional<Importer> getImporter(String name) {
|
||||
public Optional<Importer> getImporter(@Untrusted String 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.queries.objects.ServerQueries;
|
||||
import com.djrapitops.plan.storage.database.queries.objects.UserIdentifierQueries;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.inject.Inject;
|
||||
@ -63,55 +64,7 @@ public class Identifiers {
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
public static Optional<Long> getTimestamp(@Untrusted Request request) {
|
||||
try {
|
||||
long currentTime = System.currentTimeMillis();
|
||||
long timestamp = request.getQuery().get("timestamp")
|
||||
@ -125,4 +78,52 @@ public class Identifiers {
|
||||
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.storage.database.DBSystem;
|
||||
import com.djrapitops.plan.storage.database.queries.objects.UserIdentifierQueries;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
import com.djrapitops.plan.utilities.logging.ErrorLogger;
|
||||
import net.playeranalytics.plugin.player.UUIDFetcher;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@ -50,18 +51,18 @@ public class UUIDUtility {
|
||||
this.errorLogger = errorLogger;
|
||||
}
|
||||
|
||||
public static Optional<UUID> parseFromString(String uuidString) {
|
||||
public static Optional<UUID> parseFromString(@Untrusted String uuidString) {
|
||||
try {
|
||||
return Optional.of(UUID.fromString(uuidString));
|
||||
} catch (IllegalArgumentException malformedUUIDException) {
|
||||
} catch (@Untrusted IllegalArgumentException malformedUUIDException) {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
public Optional<String> getNameOf(String possiblePlayerUUID) {
|
||||
public Optional<String> getNameOf(@Untrusted String possiblePlayerUUID) {
|
||||
try {
|
||||
return getNameOf(UUID.fromString(possiblePlayerUUID));
|
||||
} catch (IllegalArgumentException notUUID) {
|
||||
} catch (@Untrusted IllegalArgumentException notUUID) {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
@ -78,7 +79,7 @@ public class UUIDUtility {
|
||||
* @return UUID of the player
|
||||
*/
|
||||
@Nullable
|
||||
public UUID getUUIDOf(String playerName) {
|
||||
public UUID getUUIDOf(@Untrusted String playerName) {
|
||||
if (playerName == null) throw new IllegalArgumentException("Player name can not be null!");
|
||||
UUID uuid = getUUIDFromString(playerName);
|
||||
if (uuid != null) return uuid;
|
||||
@ -87,23 +88,23 @@ public class UUIDUtility {
|
||||
.orElse(getUUIDViaUUIDFetcher(playerName));
|
||||
}
|
||||
|
||||
private UUID getUUIDFromString(String playerName) {
|
||||
private UUID getUUIDFromString(@Untrusted String playerName) {
|
||||
try {
|
||||
return UUID.fromString(playerName);
|
||||
} catch (IllegalArgumentException ignore) {
|
||||
} catch (@Untrusted IllegalArgumentException ignore) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private UUID getUUIDViaUUIDFetcher(String playerName) {
|
||||
private UUID getUUIDViaUUIDFetcher(@Untrusted String playerName) {
|
||||
try {
|
||||
return UUIDFetcher.getUUIDOf(playerName);
|
||||
} catch (Exception | NoClassDefFoundError ignored) {
|
||||
} catch (@Untrusted Exception | NoClassDefFoundError ignored) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private Optional<UUID> getUUIDFromDB(String playerName) {
|
||||
private Optional<UUID> getUUIDFromDB(@Untrusted String playerName) {
|
||||
try {
|
||||
return dbSystem.getDatabase().query(UserIdentifierQueries.fetchPlayerUUIDOf(playerName));
|
||||
} 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.queries.analysis.PlayerCountQueries;
|
||||
import com.djrapitops.plan.storage.database.queries.objects.ServerQueries;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
|
||||
import javax.inject.Inject;
|
||||
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);
|
||||
}
|
||||
|
||||
private Optional<ServerUUID> getServerUUIDForServerIdentifier(String serverIdentifier) {
|
||||
private Optional<ServerUUID> getServerUUIDForServerIdentifier(@Untrusted String serverIdentifier) {
|
||||
return dbSystem.getDatabase().query(ServerQueries.fetchServerMatchingIdentifier(serverIdentifier))
|
||||
.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.storage.database.DBSystem;
|
||||
import com.djrapitops.plan.storage.database.queries.containers.ContainerFetchQueries;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
@ -107,21 +108,21 @@ public final class PlanPlaceholders {
|
||||
* value found but the placeholder is registered,
|
||||
* 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()) {
|
||||
if (placeholder.startsWith(entry.getKey())) {
|
||||
return Objects.toString(entry.getValue().apply(placeholder));
|
||||
}
|
||||
}
|
||||
|
||||
Arguments arguments = new Arguments(parameters);
|
||||
@Untrusted Arguments arguments = new Arguments(parameters);
|
||||
|
||||
StaticPlaceholderLoader staticLoader = staticPlaceholders.get(placeholder);
|
||||
if (staticLoader != null) {
|
||||
return Objects.toString(staticLoader.apply(arguments));
|
||||
}
|
||||
|
||||
Optional<String> givenIdentifier = arguments.get(0);
|
||||
@Untrusted Optional<String> givenIdentifier = arguments.get(0);
|
||||
Optional<UUID> foundUUID = givenIdentifier
|
||||
.flatMap(this::getPlayerUUIDForIdentifier);
|
||||
UUID playerUUID = foundUUID.orElse(uuid);
|
||||
@ -142,7 +143,7 @@ public final class PlanPlaceholders {
|
||||
return null;
|
||||
}
|
||||
|
||||
private Optional<UUID> getPlayerUUIDForIdentifier(String identifier) {
|
||||
private Optional<UUID> getPlayerUUIDForIdentifier(@Untrusted String 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.objects.ServerQueries;
|
||||
import com.djrapitops.plan.storage.database.queries.objects.TPSQueries;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
@ -201,11 +202,11 @@ public class ServerPlaceHolders implements Placeholders {
|
||||
registerDynamicCategoryPlaceholders(placeholders, database);
|
||||
}
|
||||
|
||||
private ServerUUID getServerUUID(Arguments parameters) {
|
||||
private ServerUUID getServerUUID(@Untrusted Arguments parameters) {
|
||||
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))
|
||||
.map(Server::getUuid);
|
||||
}
|
||||
@ -242,7 +243,7 @@ public class ServerPlaceHolders implements Placeholders {
|
||||
}
|
||||
|
||||
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> {
|
||||
@ -266,7 +267,7 @@ public class ServerPlaceHolders implements Placeholders {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ import com.djrapitops.plan.storage.database.DBSystem;
|
||||
import com.djrapitops.plan.storage.database.Database;
|
||||
import com.djrapitops.plan.storage.database.queries.analysis.PlayerCountQueries;
|
||||
import com.djrapitops.plan.storage.database.queries.objects.*;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
|
||||
import javax.inject.Inject;
|
||||
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("-"));
|
||||
}
|
||||
|
||||
private ServerUUID getServerUUID(Arguments parameters) {
|
||||
private ServerUUID getServerUUID(@Untrusted Arguments parameters) {
|
||||
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))
|
||||
.map(Server::getUuid);
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
package com.djrapitops.plan.storage.database;
|
||||
|
||||
import com.djrapitops.plan.storage.database.sql.building.Sql;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -80,7 +81,7 @@ public enum DBType {
|
||||
* @param name the name of the {@code 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()) {
|
||||
if (dbType.getName().equalsIgnoreCase(name)) {
|
||||
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.UserInfoTable;
|
||||
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.ResultSet;
|
||||
|
@ -17,6 +17,7 @@
|
||||
package com.djrapitops.plan.storage.database.queries.filter;
|
||||
|
||||
import com.djrapitops.plan.delivery.domain.datatransfer.InputFilterDto;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@ -42,9 +43,9 @@ public interface Filter {
|
||||
* @return Set of UUIDs this filter applies to
|
||||
* @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 {
|
||||
return new Result(null, getKind(), getMatchingUserIds(query));
|
||||
} 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.queries.filter.filters.AllPlayersFilter;
|
||||
import com.djrapitops.plan.storage.database.queries.filter.filters.PluginGroupsFilter;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
|
||||
import javax.inject.Inject;
|
||||
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();
|
||||
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.
|
||||
* @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();
|
||||
Filter.Result current = null;
|
||||
if (filterQueries.isEmpty()) return allPlayersFilter.apply(null);
|
||||
for (InputFilterDto inputFilterDto : filterQueries) {
|
||||
for (@Untrusted InputFilterDto inputFilterDto : filterQueries) {
|
||||
current = apply(current, inputFilterDto);
|
||||
if (current != null && current.isEmpty()) break;
|
||||
}
|
||||
return current;
|
||||
}
|
||||
|
||||
private Filter.Result apply(Filter.Result current, InputFilterDto inputFilterDto) {
|
||||
String kind = inputFilterDto.getKind();
|
||||
private Filter.Result apply(Filter.Result current, @Untrusted InputFilterDto inputFilterDto) {
|
||||
@Untrusted String kind = inputFilterDto.getKind();
|
||||
Filter filter = getFilter(kind).orElseThrow(() -> new BadRequestException("Filter kind not supported: '" + kind + "'"));
|
||||
|
||||
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 {
|
||||
return current == null ? filter.apply(query) : current.apply(filter, query);
|
||||
} 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.queries.analysis.NetworkActivityIndexQueries;
|
||||
import com.djrapitops.plan.storage.database.queries.filter.CompleteSetException;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
@ -66,8 +67,8 @@ public class ActivityIndexFilter extends MultiOptionFilter {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Integer> getMatchingUserIds(InputFilterDto query) {
|
||||
List<String> selected = getSelected(query);
|
||||
public Set<Integer> getMatchingUserIds(@Untrusted InputFilterDto query) {
|
||||
@Untrusted List<String> selected = getSelected(query);
|
||||
String[] options = getOptionsArray();
|
||||
|
||||
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.queries.filter.Filter;
|
||||
import com.djrapitops.plan.storage.database.queries.objects.UserIdentifierQueries;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
@ -51,7 +52,7 @@ public class AllPlayersFilter implements Filter {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Integer> getMatchingUserIds(InputFilterDto query) {
|
||||
public Set<Integer> getMatchingUserIds(@Untrusted InputFilterDto query) {
|
||||
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.queries.filter.CompleteSetException;
|
||||
import com.djrapitops.plan.storage.database.queries.objects.UserInfoQueries;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
@ -57,8 +58,8 @@ public class BannedFilter extends MultiOptionFilter {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Integer> getMatchingUserIds(InputFilterDto query) {
|
||||
List<String> selected = getSelected(query);
|
||||
public Set<Integer> getMatchingUserIds(@Untrusted InputFilterDto query) {
|
||||
@Untrusted List<String> selected = getSelected(query);
|
||||
Set<Integer> userIds = new HashSet<>();
|
||||
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.queries.filter.Filter;
|
||||
import com.djrapitops.plan.storage.database.queries.objects.BaseUserQueries;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
import com.djrapitops.plan.utilities.java.Maps;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
@ -61,17 +62,17 @@ public abstract class DateRangeFilter implements Filter {
|
||||
.build();
|
||||
}
|
||||
|
||||
protected long getAfter(InputFilterDto query) {
|
||||
protected long getAfter(@Untrusted InputFilterDto query) {
|
||||
return getTime(query, "afterDate", "afterTime");
|
||||
}
|
||||
|
||||
protected long getBefore(InputFilterDto query) {
|
||||
protected long getBefore(@Untrusted InputFilterDto query) {
|
||||
return getTime(query, "beforeDate", "beforeTime");
|
||||
}
|
||||
|
||||
private long getTime(InputFilterDto query, String dateKey, String timeKey) {
|
||||
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()));
|
||||
private long getTime(@Untrusted InputFilterDto query, String dateKey, String timeKey) {
|
||||
@Untrusted String date = query.get(dateKey).orElseThrow(() -> new BadRequestException("'" + dateKey + "' not specified in parameters for " + getKind()));
|
||||
@Untrusted String time = query.get(timeKey).orElseThrow(() -> new BadRequestException("'" + timeKey + "' not specified in parameters for " + getKind()));
|
||||
|
||||
try {
|
||||
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.storage.database.DBSystem;
|
||||
import com.djrapitops.plan.storage.database.queries.objects.GeoInfoQueries;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
@ -50,7 +51,7 @@ public class GeolocationsFilter extends MultiOptionFilter {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Integer> getMatchingUserIds(InputFilterDto query) {
|
||||
public Set<Integer> getMatchingUserIds(@Untrusted InputFilterDto 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.storage.database.DBSystem;
|
||||
import com.djrapitops.plan.storage.database.queries.objects.JoinAddressQueries;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
@ -50,7 +51,7 @@ public class JoinAddressFilter extends MultiOptionFilter {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Integer> getMatchingUserIds(InputFilterDto query) {
|
||||
public Set<Integer> getMatchingUserIds(@Untrusted InputFilterDto 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.storage.database.queries.filter.CompleteSetException;
|
||||
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.reflect.TypeToken;
|
||||
|
||||
@ -31,9 +32,9 @@ public abstract class MultiOptionFilter implements Filter {
|
||||
return new String[]{"selected"};
|
||||
}
|
||||
|
||||
protected List<String> getSelected(InputFilterDto query) {
|
||||
String selectedJSON = query.get("selected").orElseThrow(IllegalArgumentException::new);
|
||||
List<String> selected = new Gson().fromJson(selectedJSON, new TypeToken<List<String>>() {}.getType());
|
||||
protected List<String> getSelected(@Untrusted InputFilterDto query) {
|
||||
@Untrusted String selectedJSON = query.get("selected").orElseThrow(IllegalArgumentException::new);
|
||||
@Untrusted List<String> selected = new Gson().fromJson(selectedJSON, new TypeToken<List<String>>() {}.getType());
|
||||
if (selected.isEmpty()) throw new CompleteSetException();
|
||||
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.queries.filter.CompleteSetException;
|
||||
import com.djrapitops.plan.storage.database.queries.objects.UserInfoQueries;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
@ -57,8 +58,8 @@ public class OperatorsFilter extends MultiOptionFilter {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Integer> getMatchingUserIds(InputFilterDto query) {
|
||||
List<String> selected = getSelected(query);
|
||||
public Set<Integer> getMatchingUserIds(@Untrusted InputFilterDto query) {
|
||||
@Untrusted List<String> selected = getSelected(query);
|
||||
Set<Integer> userIds = new HashSet<>();
|
||||
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.queries.objects.ServerQueries;
|
||||
import com.djrapitops.plan.storage.database.queries.objects.SessionQueries;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
import com.google.gson.Gson;
|
||||
|
||||
import javax.inject.Inject;
|
||||
@ -47,10 +48,10 @@ public class PlayedBetweenDateRangeFilter extends DateRangeFilter {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Integer> getMatchingUserIds(InputFilterDto query) {
|
||||
public Set<Integer> getMatchingUserIds(@Untrusted InputFilterDto query) {
|
||||
long after = getAfter(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));
|
||||
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.queries.objects.ServerQueries;
|
||||
import com.djrapitops.plan.storage.database.queries.objects.UserInfoQueries;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
@ -54,8 +55,8 @@ public class PlayedOnServerFilter extends MultiOptionFilter {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Integer> getMatchingUserIds(InputFilterDto query) {
|
||||
List<String> serverNames = getSelected(query);
|
||||
public Set<Integer> getMatchingUserIds(@Untrusted InputFilterDto query) {
|
||||
@Untrusted List<String> serverNames = getSelected(query);
|
||||
List<ServerUUID> serverUUIDs = serverNames.isEmpty() ? Collections.emptyList() : dbSystem.getDatabase().query(ServerQueries.fetchServersMatchingIdentifiers(serverNames));
|
||||
|
||||
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.objects.ServerQueries;
|
||||
import com.djrapitops.plan.storage.database.sql.tables.*;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
@ -81,13 +83,13 @@ public class PluginBooleanGroupFilter extends MultiOptionFilter {
|
||||
}
|
||||
|
||||
private static Query<Set<Integer>> playersInGroups(
|
||||
Map<PluginBooleanOption, SelectedBoolean> selected,
|
||||
@Untrusted Map<PluginBooleanOption, SelectedBoolean> selected,
|
||||
Map<String, ServerUUID> namesToUUIDs
|
||||
) {
|
||||
return db -> {
|
||||
Set<Integer> userIds = new HashSet<>();
|
||||
for (Map.Entry<PluginBooleanOption, SelectedBoolean> option : selected.entrySet()) {
|
||||
PluginBooleanOption pluginBooleanOption = option.getKey();
|
||||
@Untrusted PluginBooleanOption pluginBooleanOption = option.getKey();
|
||||
SelectedBoolean selectedBoolean = option.getValue();
|
||||
userIds.addAll(
|
||||
db.query(playersInGroup(
|
||||
@ -103,8 +105,12 @@ public class PluginBooleanGroupFilter extends MultiOptionFilter {
|
||||
}
|
||||
|
||||
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" +
|
||||
FROM + ExtensionPluginTable.TABLE_NAME + " plugin" +
|
||||
INNER_JOIN + ExtensionProviderTable.TABLE_NAME + " provider on provider." + ExtensionProviderTable.PLUGIN_ID + "=plugin." + ExtensionPluginTable.ID +
|
||||
@ -162,12 +168,12 @@ public class PluginBooleanGroupFilter extends MultiOptionFilter {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Integer> getMatchingUserIds(InputFilterDto query) {
|
||||
Map<PluginBooleanOption, SelectedBoolean> selectedBooleanOptions = new HashMap<>();
|
||||
for (String selected : getSelected(query)) {
|
||||
String[] optionAndBoolean = StringUtils.split(selected, ":", 2);
|
||||
PluginBooleanOption pluginBooleanOption = PluginBooleanOption.parse(optionAndBoolean[0].trim());
|
||||
String selectedBoolean = optionAndBoolean[1].trim().toUpperCase();
|
||||
public Set<Integer> getMatchingUserIds(@Untrusted InputFilterDto query) {
|
||||
@Untrusted Map<PluginBooleanOption, SelectedBoolean> selectedBooleanOptions = new HashMap<>();
|
||||
for (@Untrusted String selected : getSelected(query)) {
|
||||
@Untrusted String[] optionAndBoolean = StringUtils.split(selected, ":", 2);
|
||||
@Untrusted PluginBooleanOption pluginBooleanOption = PluginBooleanOption.parse(optionAndBoolean[0].trim());
|
||||
@Untrusted String selectedBoolean = optionAndBoolean[1].trim().toUpperCase();
|
||||
selectedBooleanOptions.computeIfPresent(pluginBooleanOption, (key, existing) -> SelectedBoolean.BOTH);
|
||||
selectedBooleanOptions.computeIfAbsent(pluginBooleanOption, key -> SelectedBoolean.valueOf(selectedBoolean));
|
||||
}
|
||||
@ -183,6 +189,7 @@ public class PluginBooleanGroupFilter extends MultiOptionFilter {
|
||||
BOTH
|
||||
}
|
||||
|
||||
@Untrusted
|
||||
public static class PluginBooleanOption implements Comparable<PluginBooleanOption> {
|
||||
private final String serverName;
|
||||
private final String pluginName;
|
||||
@ -194,12 +201,13 @@ public class PluginBooleanGroupFilter extends MultiOptionFilter {
|
||||
this.providerText = providerText;
|
||||
}
|
||||
|
||||
public static PluginBooleanOption parse(String fromFormatted) {
|
||||
String[] split1 = StringUtils.split(fromFormatted, ",", 2);
|
||||
String[] split2 = StringUtils.split(split1[1], "-", 2);
|
||||
String serverName = split1[0].trim();
|
||||
String pluginName = split2[0].trim();
|
||||
String providerName = split2[1].trim();
|
||||
@Untrusted
|
||||
public static PluginBooleanOption parse(@Untrusted String fromFormatted) {
|
||||
@Untrusted String[] split1 = StringUtils.split(fromFormatted, ",", 2);
|
||||
@Untrusted String[] split2 = StringUtils.split(split1[1], "-", 2);
|
||||
@Untrusted String serverName = split1[0].trim();
|
||||
@Untrusted String pluginName = split2[0].trim();
|
||||
@Untrusted String providerName = split2[1].trim();
|
||||
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.ExtensionProviderTable;
|
||||
import com.djrapitops.plan.storage.database.sql.tables.ServerTable;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
import com.djrapitops.plan.utilities.java.Maps;
|
||||
|
||||
import javax.inject.Inject;
|
||||
@ -67,7 +68,7 @@ public class PluginGroupsFilter extends MultiOptionFilter {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Integer> getMatchingUserIds(InputFilterDto query) {
|
||||
public Set<Integer> getMatchingUserIds(@Untrusted InputFilterDto query) {
|
||||
return dbSystem.getDatabase().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.ServerQueries;
|
||||
import com.djrapitops.plan.storage.database.queries.objects.UserInfoQueries;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
import com.google.gson.Gson;
|
||||
|
||||
import javax.inject.Inject;
|
||||
@ -48,10 +49,10 @@ public class RegisteredBetweenDateRangeFilter extends DateRangeFilter {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Integer> getMatchingUserIds(InputFilterDto query) {
|
||||
public Set<Integer> getMatchingUserIds(@Untrusted InputFilterDto query) {
|
||||
long after = getAfter(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));
|
||||
return dbSystem.getDatabase().query(
|
||||
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")
|
||||
.map(serversList -> new Gson().fromJson(serversList, String[].class))
|
||||
.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.QueryAllStatement;
|
||||
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.ServerTable;
|
||||
import com.djrapitops.plan.storage.database.sql.tables.UserInfoTable;
|
||||
import com.djrapitops.plan.storage.database.sql.tables.UsersTable;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
import com.djrapitops.plan.utilities.java.Lists;
|
||||
import org.apache.commons.text.TextStringBuilder;
|
||||
|
||||
@ -166,14 +168,12 @@ public class GeoInfoQueries {
|
||||
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 +
|
||||
FROM + GeoInfoTable.TABLE_NAME + " g" +
|
||||
INNER_JOIN + UsersTable.TABLE_NAME + " u on u.id=g." + GeoInfoTable.USER_ID +
|
||||
WHERE + GeoInfoTable.GEOLOCATION +
|
||||
" IN ('" +
|
||||
new TextStringBuilder().appendWithSeparators(selected, "','") +
|
||||
"')";
|
||||
return db -> db.querySet(sql, RowExtractors.getInt(UsersTable.ID));
|
||||
" IN (" + Sql.nParameters(selected.size()) + ")";
|
||||
return db -> db.querySet(sql, RowExtractors.getInt(UsersTable.ID), selected);
|
||||
}
|
||||
}
|
@ -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.ServerTable;
|
||||
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.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 +
|
||||
FROM + JoinAddressTable.TABLE_NAME + " j" +
|
||||
INNER_JOIN + SessionsTable.TABLE_NAME + " s on s." + SessionsTable.JOIN_ADDRESS_ID + "=j." + JoinAddressTable.ID +
|
||||
WHERE + JoinAddressTable.JOIN_ADDRESS + " IN (" +
|
||||
new TextStringBuilder().appendWithSeparators(joinAddresses.stream().map(item -> '?').iterator(), ",") +
|
||||
nParameters(joinAddresses.size()) +
|
||||
')'; // Don't append addresses directly, SQL injection hazard
|
||||
|
||||
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.sql.building.Select;
|
||||
import com.djrapitops.plan.storage.database.sql.tables.ServerTable;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
import com.djrapitops.plan.utilities.java.Maps;
|
||||
import org.apache.commons.lang3.math.NumberUtils;
|
||||
|
||||
@ -110,7 +111,7 @@ public class ServerQueries {
|
||||
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 +
|
||||
WHERE + "(LOWER(" + ServerTable.SERVER_UUID + ") LIKE LOWER(?)" +
|
||||
OR + "LOWER(" + ServerTable.NAME + ") LIKE LOWER(?)" +
|
||||
@ -283,7 +284,7 @@ public class ServerQueries {
|
||||
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 -> {
|
||||
Map<String, ServerUUID> nameToUUIDMap = db.query(ServerQueries.fetchServerNamesToUUIDs());
|
||||
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.QueryStatement;
|
||||
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 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.UserInfoTable;
|
||||
import com.djrapitops.plan.storage.database.sql.tables.UsersTable;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
@ -125,7 +126,7 @@ public class UserIdentifierQueries {
|
||||
* @param playerName Name of the player, case does not matter.
|
||||
* @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)
|
||||
.where("UPPER(" + UsersTable.USER_NAME + ")=UPPER(?)")
|
||||
.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 +
|
||||
FROM + UsersTable.TABLE_NAME +
|
||||
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.SecurityTable;
|
||||
import com.djrapitops.plan.storage.database.sql.tables.UsersTable;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
@ -43,7 +44,7 @@ public class WebUserQueries {
|
||||
/* 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 +
|
||||
LEFT_JOIN + UsersTable.TABLE_NAME + " on " + SecurityTable.LINKED_TO + "=" + UsersTable.USER_UUID +
|
||||
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.transactions.ExecStatement;
|
||||
import com.djrapitops.plan.storage.database.transactions.Transaction;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
@ -26,10 +27,11 @@ import java.sql.SQLException;
|
||||
public class CookieChangeTransaction extends Transaction {
|
||||
|
||||
private final String username;
|
||||
@Untrusted
|
||||
private final String cookie; // Null if removing
|
||||
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.cookie = cookie;
|
||||
this.expires = expires;
|
||||
@ -43,7 +45,7 @@ public class CookieChangeTransaction extends Transaction {
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -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.transactions.ExecStatement;
|
||||
import com.djrapitops.plan.storage.database.transactions.Transaction;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
@ -33,10 +34,11 @@ import static com.djrapitops.plan.storage.database.sql.building.Sql.*;
|
||||
|
||||
public class StoreJoinAddressTransaction extends Transaction {
|
||||
|
||||
@Untrusted
|
||||
private final Supplier<String> joinAddress;
|
||||
private int newId;
|
||||
|
||||
public StoreJoinAddressTransaction(String joinAddress) {
|
||||
public StoreJoinAddressTransaction(@Untrusted String joinAddress) {
|
||||
this(() -> joinAddress);
|
||||
}
|
||||
|
||||
@ -56,12 +58,13 @@ public class StoreJoinAddressTransaction extends Transaction {
|
||||
return new HasMoreThanZeroQueryStatement(sql) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
String address = getAddress();
|
||||
@Untrusted String address = getAddress();
|
||||
statement.setString(1, address);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Untrusted
|
||||
private String getAddress() {
|
||||
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.settings.config.PlanConfig;
|
||||
import com.djrapitops.plan.settings.config.paths.CustomizedFileSettings;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
import dagger.Lazy;
|
||||
|
||||
import javax.inject.Inject;
|
||||
@ -90,7 +91,7 @@ public class PlanFiles implements SubSystem {
|
||||
return getFileFromPluginFolder("locale.yml");
|
||||
}
|
||||
|
||||
public File getFileFromPluginFolder(String name) {
|
||||
public File getFileFromPluginFolder(@Untrusted String name) {
|
||||
return new File(dataFolder, name.replace("/", File.separator));
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
package com.djrapitops.plan.utilities;
|
||||
|
||||
import com.djrapitops.plan.exceptions.PassEncryptException;
|
||||
import com.djrapitops.plan.utilities.dev.Untrusted;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import javax.crypto.SecretKeyFactory;
|
||||
@ -62,7 +63,7 @@ public class PassEncryptUtil {
|
||||
* @return Hash + salt
|
||||
* @throws CannotPerformOperationException If the hash creation fails
|
||||
*/
|
||||
public static String createHash(String password) {
|
||||
public static String createHash(@Untrusted String password) {
|
||||
return createHash(password.toCharArray());
|
||||
}
|
||||
|
||||
@ -93,7 +94,7 @@ public class PassEncryptUtil {
|
||||
* @throws CannotPerformOperationException If hashing fails
|
||||
* @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);
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
* 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;
|
||||
package com.djrapitops.plan.utilities.dev;
|
||||
|
||||
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