mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2024-11-08 20:01:20 +01:00
Merge branch '3.6.0' into master
This commit is contained in:
commit
d1be610e96
@ -42,11 +42,14 @@ import main.java.com.djrapitops.plan.utilities.Benchmark;
|
|||||||
import main.java.com.djrapitops.plan.utilities.Check;
|
import main.java.com.djrapitops.plan.utilities.Check;
|
||||||
import main.java.com.djrapitops.plan.utilities.MiscUtils;
|
import main.java.com.djrapitops.plan.utilities.MiscUtils;
|
||||||
import main.java.com.djrapitops.plan.utilities.metrics.BStats;
|
import main.java.com.djrapitops.plan.utilities.metrics.BStats;
|
||||||
import org.bukkit.Bukkit;
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.core.LoggerContext;
|
||||||
|
import org.apache.logging.log4j.core.config.LoggerConfig;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
@ -186,7 +189,11 @@ public class Plan extends BukkitPlugin<Plan> {
|
|||||||
Log.error("WebServer was not Initialized.");
|
Log.error("WebServer was not Initialized.");
|
||||||
}
|
}
|
||||||
// Prevent passwords showing up on console.
|
// Prevent passwords showing up on console.
|
||||||
Bukkit.getLogger().setFilter(new RegisterCommandFilter());
|
LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
|
||||||
|
Collection<LoggerConfig> lc = ctx.getConfiguration().getLoggers().values();
|
||||||
|
for (LoggerConfig c : lc) {
|
||||||
|
c.addFilter(new RegisterCommandFilter());
|
||||||
|
}
|
||||||
} else if (!hasDataViewCapability) {
|
} else if (!hasDataViewCapability) {
|
||||||
Log.infoColor(Phrase.ERROR_NO_DATA_VIEW.toString());
|
Log.infoColor(Phrase.ERROR_NO_DATA_VIEW.toString());
|
||||||
}
|
}
|
||||||
@ -390,7 +397,7 @@ public class Plan extends BukkitPlugin<Plan> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try (InputStream inputStream = localeURL.openStream();
|
try (InputStream inputStream = localeURL.openStream();
|
||||||
OutputStream outputStream = new FileOutputStream(localeFile)) {
|
OutputStream outputStream = new FileOutputStream(localeFile)) {
|
||||||
|
|
||||||
int read;
|
int read;
|
||||||
byte[] bytes = new byte[1024];
|
byte[] bytes = new byte[1024];
|
||||||
@ -421,9 +428,8 @@ public class Plan extends BukkitPlugin<Plan> {
|
|||||||
/**
|
/**
|
||||||
* Stops initializing the locale
|
* Stops initializing the locale
|
||||||
*
|
*
|
||||||
* @implNote Removes clutter in the method
|
|
||||||
*
|
|
||||||
* @param usingLocale The locale that's used
|
* @param usingLocale The locale that's used
|
||||||
|
* @implNote Removes clutter in the method
|
||||||
*/
|
*/
|
||||||
private void stopInitLocale(String usingLocale) {
|
private void stopInitLocale(String usingLocale) {
|
||||||
Benchmark.stop("Enable: Initializing locale");
|
Benchmark.stop("Enable: Initializing locale");
|
||||||
|
@ -53,7 +53,7 @@ public enum Settings {
|
|||||||
WEBSERVER_CERTIFICATE_KEYPASS("Settings.WebServer.Security.Certificate.KeyPass"),
|
WEBSERVER_CERTIFICATE_KEYPASS("Settings.WebServer.Security.Certificate.KeyPass"),
|
||||||
WEBSERVER_CERTIFICATE_STOREPASS("Settings.WebServer.Security.Certificate.KeyPass"),
|
WEBSERVER_CERTIFICATE_STOREPASS("Settings.WebServer.Security.Certificate.KeyPass"),
|
||||||
WEBSERVER_CERTIFICATE_ALIAS("Settings.WebServer.Security.Certificate.Alias"),
|
WEBSERVER_CERTIFICATE_ALIAS("Settings.WebServer.Security.Certificate.Alias"),
|
||||||
LINK_PROTOCOL("Settings.WebServer.LinkProtocol"),
|
LINK_PROTOCOL("Settings.WebServer.ExternalWebServerLinkProtocol"),
|
||||||
//
|
//
|
||||||
SERVER_NAME("Customization.ServerName"),
|
SERVER_NAME("Customization.ServerName"),
|
||||||
//
|
//
|
||||||
|
@ -68,23 +68,25 @@ public class AnalyzeCommand extends SubCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sender.sendMessage(Phrase.GRABBING_DATA_MESSAGE + "");
|
sender.sendMessage(Phrase.GRABBING_DATA_MESSAGE + "");
|
||||||
plugin.getRunnableFactory().createNew(new AbsRunnable("WebUser exist check task") {
|
if (plugin.getUiServer().isAuthRequired()) {
|
||||||
@Override
|
plugin.getRunnableFactory().createNew(new AbsRunnable("WebUser exist check task") {
|
||||||
public void run() {
|
@Override
|
||||||
try {
|
public void run() {
|
||||||
if (CommandUtils.isPlayer(sender)) {
|
try {
|
||||||
boolean senderHasWebUser = plugin.getDB().getSecurityTable().userExists(sender.getName());
|
if (CommandUtils.isPlayer(sender)) {
|
||||||
if (!senderHasWebUser) {
|
boolean senderHasWebUser = plugin.getDB().getSecurityTable().userExists(sender.getName());
|
||||||
sender.sendMessage(ChatColor.YELLOW + "[Plan] You might not have a web user, use /plan register <password>");
|
if (!senderHasWebUser) {
|
||||||
|
sender.sendMessage(ChatColor.YELLOW + "[Plan] You might not have a web user, use /plan register <password>");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.toLog(this.getClass().getName() + getName(), e);
|
||||||
|
} finally {
|
||||||
|
this.cancel();
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
|
||||||
Log.toLog(this.getClass().getName() + getName(), e);
|
|
||||||
} finally {
|
|
||||||
this.cancel();
|
|
||||||
}
|
}
|
||||||
}
|
}).runTaskAsynchronously();
|
||||||
}).runTaskAsynchronously();
|
}
|
||||||
updateCache();
|
updateCache();
|
||||||
runMessageSenderTask(sender);
|
runMessageSenderTask(sender);
|
||||||
return true;
|
return true;
|
||||||
|
@ -90,7 +90,7 @@ public class InspectCommand extends SubCommand {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
sender.sendMessage(Phrase.GRABBING_DATA_MESSAGE + "");
|
sender.sendMessage(Phrase.GRABBING_DATA_MESSAGE + "");
|
||||||
if (CommandUtils.isPlayer(sender)) {
|
if (CommandUtils.isPlayer(sender) && plugin.getUiServer().isAuthRequired()) {
|
||||||
boolean senderHasWebUser = plugin.getDB().getSecurityTable().userExists(sender.getName());
|
boolean senderHasWebUser = plugin.getDB().getSecurityTable().userExists(sender.getName());
|
||||||
if (!senderHasWebUser) {
|
if (!senderHasWebUser) {
|
||||||
sender.sendMessage(ChatColor.YELLOW + "[Plan] You might not have a web user, use /plan register <password>");
|
sender.sendMessage(ChatColor.YELLOW + "[Plan] You might not have a web user, use /plan register <password>");
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
package main.java.com.djrapitops.plan.command.commands;
|
package main.java.com.djrapitops.plan.command.commands;
|
||||||
|
|
||||||
import java.util.logging.Filter;
|
import org.apache.logging.log4j.Level;
|
||||||
import java.util.logging.LogRecord;
|
import org.apache.logging.log4j.Marker;
|
||||||
|
import org.apache.logging.log4j.core.Filter;
|
||||||
|
import org.apache.logging.log4j.core.LogEvent;
|
||||||
|
import org.apache.logging.log4j.core.Logger;
|
||||||
|
import org.apache.logging.log4j.message.Message;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filters out WebUser registration command logs.
|
* Filters out WebUser registration command logs.
|
||||||
@ -11,12 +15,126 @@ import java.util.logging.LogRecord;
|
|||||||
*/
|
*/
|
||||||
public class RegisterCommandFilter implements Filter {
|
public class RegisterCommandFilter implements Filter {
|
||||||
|
|
||||||
@Override
|
private boolean start = true;
|
||||||
public boolean isLoggable(LogRecord record) {
|
|
||||||
String message = record.getMessage();
|
private Result filter(String message) {
|
||||||
boolean block = message.contains("command: /plan register")
|
boolean block = message.contains("command: /plan register")
|
||||||
|| message.contains("command: /plan web register")
|
|| message.contains("command: /plan web register")
|
||||||
|| message.contains("command: /plan webuser register");
|
|| message.contains("command: /plan webuser register");
|
||||||
return !block;
|
if (block) {
|
||||||
|
return Result.DENY;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Result filter(LogEvent event) {
|
||||||
|
String message = event.getMessage().toString().toLowerCase();
|
||||||
|
return filter(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Result filter(Logger arg0, Level arg1, Marker arg2, String arg3, Object... arg4) {
|
||||||
|
return filter(arg3);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Result filter(Logger arg0, Level arg1, Marker arg2, Object arg3, Throwable arg4) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Result filter(Logger arg0, Level arg1, Marker arg2, Message arg3, Throwable arg4) {
|
||||||
|
return filter(arg3.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Result getOnMatch() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Result getOnMismatch() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Result filter(Logger logger, Level level, Marker marker, String s, Object o) {
|
||||||
|
return filter(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Result filter(Logger logger, Level level, Marker marker, String s, Object o, Object o1) {
|
||||||
|
return filter(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Result filter(Logger logger, Level level, Marker marker, String s, Object o, Object o1, Object o2) {
|
||||||
|
return filter(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Result filter(Logger logger, Level level, Marker marker, String s, Object o, Object o1, Object o2, Object o3) {
|
||||||
|
return filter(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Result filter(Logger logger, Level level, Marker marker, String s, Object o, Object o1, Object o2, Object o3, Object o4) {
|
||||||
|
return filter(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Result filter(Logger logger, Level level, Marker marker, String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5) {
|
||||||
|
return filter(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Result filter(Logger logger, Level level, Marker marker, String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6) {
|
||||||
|
return filter(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Result filter(Logger logger, Level level, Marker marker, String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7) {
|
||||||
|
return filter(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Result filter(Logger logger, Level level, Marker marker, String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7, Object o8) {
|
||||||
|
return filter(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Result filter(Logger logger, Level level, Marker marker, String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7, Object o8, Object o9) {
|
||||||
|
return filter(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public State getState() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initialize() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void start() {
|
||||||
|
start = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stop() {
|
||||||
|
start = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isStarted() {
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isStopped() {
|
||||||
|
return !start;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -805,7 +805,6 @@ public class UserData {
|
|||||||
result = 31 * result + deaths;
|
result = 31 * result + deaths;
|
||||||
result = 31 * result + name.hashCode();
|
result = 31 * result + name.hashCode();
|
||||||
result = 31 * result + (isOnline ? 1 : 0);
|
result = 31 * result + (isOnline ? 1 : 0);
|
||||||
result = 31 * result + currentSession.hashCode();
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ import java.util.*;
|
|||||||
public class DataCacheHandler extends SessionCache {
|
public class DataCacheHandler extends SessionCache {
|
||||||
|
|
||||||
// Cache
|
// Cache
|
||||||
private final HashMap<UUID, UserData> dataCache;
|
private final Map<UUID, UserData> dataCache;
|
||||||
|
|
||||||
// Plan
|
// Plan
|
||||||
private final Plan plugin;
|
private final Plan plugin;
|
||||||
|
@ -199,15 +199,17 @@ public class NicknamesTable extends Table {
|
|||||||
lastNicks.put(id, nickname);
|
lastNicks.put(id, nickname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (Map.Entry<Integer, String> entry : lastNicks.entrySet()) {
|
||||||
//TODO figure out what the heck that method does @Rsl1122
|
Integer id = entry.getKey();
|
||||||
for (Map.Entry<Integer, String> entrySet : lastNicks.entrySet()) {
|
String lastNick = entry.getValue();
|
||||||
Integer id = entrySet.getKey();
|
|
||||||
String lastNick = entrySet.getValue();
|
|
||||||
|
|
||||||
List<String> list = nicks.get(id);
|
List<String> list = nicks.get(id);
|
||||||
list.remove(lastNick); //NOTE: Remove here?
|
|
||||||
list.add(lastNick); //NOTE: And add here again?
|
// Moves the last known nickname to the end of the List.
|
||||||
|
// This is due to the way nicknames are added to UserData,
|
||||||
|
// Nicknames are stored as a Set and last Nickname is a separate String.
|
||||||
|
list.remove(lastNick);
|
||||||
|
list.add(lastNick);
|
||||||
}
|
}
|
||||||
|
|
||||||
return nicks;
|
return nicks;
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package main.java.com.djrapitops.plan.ui.html.graphs;
|
package main.java.com.djrapitops.plan.ui.html.graphs;
|
||||||
|
|
||||||
import main.java.com.djrapitops.plan.Log;
|
|
||||||
import main.java.com.djrapitops.plan.data.SessionData;
|
import main.java.com.djrapitops.plan.data.SessionData;
|
||||||
import main.java.com.djrapitops.plan.data.TPS;
|
import main.java.com.djrapitops.plan.data.TPS;
|
||||||
import main.java.com.djrapitops.plan.utilities.MiscUtils;
|
import main.java.com.djrapitops.plan.utilities.MiscUtils;
|
||||||
@ -41,8 +40,6 @@ public class PlayerActivityGraphCreator {
|
|||||||
.map(session -> new Point[]{new Point(session.getSessionStart(), 1), new Point(session.getSessionEnd(), 0)})
|
.map(session -> new Point[]{new Point(session.getSessionStart(), 1), new Point(session.getSessionEnd(), 0)})
|
||||||
.flatMap(Arrays::stream)
|
.flatMap(Arrays::stream)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
Log.debug(points.stream().map(Point::getY).collect(Collectors.toList()).toString());
|
|
||||||
return ScatterGraphCreator.scatterGraph(points, true, false);
|
return ScatterGraphCreator.scatterGraph(points, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,66 +0,0 @@
|
|||||||
package main.java.com.djrapitops.plan.ui.webserver;
|
|
||||||
|
|
||||||
import com.sun.net.httpserver.BasicAuthenticator;
|
|
||||||
import main.java.com.djrapitops.plan.Log;
|
|
||||||
import main.java.com.djrapitops.plan.Plan;
|
|
||||||
import main.java.com.djrapitops.plan.data.WebUser;
|
|
||||||
import main.java.com.djrapitops.plan.database.tables.SecurityTable;
|
|
||||||
import main.java.com.djrapitops.plan.utilities.PassEncryptUtil;
|
|
||||||
|
|
||||||
import java.sql.SQLException;
|
|
||||||
|
|
||||||
public class Authenticator extends BasicAuthenticator {
|
|
||||||
|
|
||||||
private final Plan plugin;
|
|
||||||
|
|
||||||
public Authenticator(Plan plugin, String realm) {
|
|
||||||
super(realm);
|
|
||||||
this.plugin = plugin;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean checkCredentials(String user, String pwd) {
|
|
||||||
try {
|
|
||||||
return isAuthorized(user, pwd, this.realm);
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.toLog(this.getClass().getName(), e);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isAuthorized(String user, String passwordRaw, String target) throws PassEncryptUtil.CannotPerformOperationException, PassEncryptUtil.InvalidHashException, SQLException {
|
|
||||||
SecurityTable securityTable = plugin.getDB().getSecurityTable();
|
|
||||||
if (!securityTable.userExists(user)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
WebUser securityInfo = securityTable.getSecurityInfo(user);
|
|
||||||
|
|
||||||
boolean correctPass = PassEncryptUtil.verifyPassword(passwordRaw, securityInfo.getSaltedPassHash());
|
|
||||||
if (!correctPass) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
int permLevel = securityInfo.getPermLevel(); // Lower number has higher clearance.
|
|
||||||
int required = getRequiredPermLevel(target, securityInfo.getName());
|
|
||||||
return permLevel <= required;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getRequiredPermLevel(String target, String user) {
|
|
||||||
String[] t = target.split("/");
|
|
||||||
if (t.length < 3) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
final String wantedUser = t[2].toLowerCase().trim();
|
|
||||||
final String theUser = user.trim().toLowerCase();
|
|
||||||
if (t[1].equals("players")) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (t[1].equals("player")) {
|
|
||||||
if (wantedUser.equals(theUser)) {
|
|
||||||
return 2;
|
|
||||||
} else {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,25 +1,30 @@
|
|||||||
package main.java.com.djrapitops.plan.ui.webserver;
|
package main.java.com.djrapitops.plan.ui.webserver;
|
||||||
|
|
||||||
|
import com.djrapitops.plugin.utilities.Verify;
|
||||||
import com.sun.net.httpserver.*;
|
import com.sun.net.httpserver.*;
|
||||||
import main.java.com.djrapitops.plan.Log;
|
import main.java.com.djrapitops.plan.Log;
|
||||||
import main.java.com.djrapitops.plan.Phrase;
|
import main.java.com.djrapitops.plan.Phrase;
|
||||||
import main.java.com.djrapitops.plan.Plan;
|
import main.java.com.djrapitops.plan.Plan;
|
||||||
import main.java.com.djrapitops.plan.Settings;
|
import main.java.com.djrapitops.plan.Settings;
|
||||||
|
import main.java.com.djrapitops.plan.data.WebUser;
|
||||||
|
import main.java.com.djrapitops.plan.database.tables.SecurityTable;
|
||||||
import main.java.com.djrapitops.plan.ui.html.DataRequestHandler;
|
import main.java.com.djrapitops.plan.ui.html.DataRequestHandler;
|
||||||
import main.java.com.djrapitops.plan.ui.webserver.response.*;
|
import main.java.com.djrapitops.plan.ui.webserver.response.*;
|
||||||
import main.java.com.djrapitops.plan.utilities.HtmlUtils;
|
import main.java.com.djrapitops.plan.utilities.HtmlUtils;
|
||||||
|
import main.java.com.djrapitops.plan.utilities.MiscUtils;
|
||||||
|
import main.java.com.djrapitops.plan.utilities.PassEncryptUtil;
|
||||||
import main.java.com.djrapitops.plan.utilities.uuid.UUIDUtility;
|
import main.java.com.djrapitops.plan.utilities.uuid.UUIDUtility;
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
|
||||||
import javax.net.ssl.*;
|
import javax.net.ssl.*;
|
||||||
import java.io.FileInputStream;
|
import java.io.*;
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.security.*;
|
import java.security.*;
|
||||||
import java.security.cert.Certificate;
|
import java.security.cert.Certificate;
|
||||||
import java.security.cert.CertificateException;
|
import java.security.cert.CertificateException;
|
||||||
|
import java.util.Base64;
|
||||||
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.ArrayBlockingQueue;
|
import java.util.concurrent.ArrayBlockingQueue;
|
||||||
import java.util.concurrent.ThreadPoolExecutor;
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
@ -35,7 +40,8 @@ public class WebServer {
|
|||||||
private boolean enabled = false;
|
private boolean enabled = false;
|
||||||
private HttpServer server;
|
private HttpServer server;
|
||||||
private final int port;
|
private final int port;
|
||||||
private boolean shutdown;
|
|
||||||
|
private boolean usingHttps;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class Constructor.
|
* Class Constructor.
|
||||||
@ -47,7 +53,6 @@ public class WebServer {
|
|||||||
public WebServer(Plan plugin) {
|
public WebServer(Plan plugin) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
this.port = Settings.WEBSERVER_PORT.getNumber();
|
this.port = Settings.WEBSERVER_PORT.getNumber();
|
||||||
shutdown = false;
|
|
||||||
dataReqHandler = new DataRequestHandler(plugin);
|
dataReqHandler = new DataRequestHandler(plugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,83 +67,51 @@ public class WebServer {
|
|||||||
|
|
||||||
Log.info(Phrase.WEBSERVER_INIT.toString());
|
Log.info(Phrase.WEBSERVER_INIT.toString());
|
||||||
try {
|
try {
|
||||||
String keyStorePath = Settings.WEBSERVER_CERTIFICATE_PATH.toString();
|
usingHttps = startHttpsServer();
|
||||||
if (!keyStorePath.contains(":")) {
|
|
||||||
keyStorePath = plugin.getDataFolder() + keyStorePath;
|
|
||||||
}
|
|
||||||
char[] storepass = Settings.WEBSERVER_CERTIFICATE_STOREPASS.toString().toCharArray();
|
|
||||||
char[] keypass = Settings.WEBSERVER_CERTIFICATE_KEYPASS.toString().toCharArray();
|
|
||||||
String alias = Settings.WEBSERVER_CERTIFICATE_ALIAS.toString();
|
|
||||||
|
|
||||||
boolean startSuccessful = false;
|
Log.debug(usingHttps ? "Https Start Successful." : "Https Start Failed.");
|
||||||
try (FileInputStream fIn = new FileInputStream(keyStorePath)) {
|
|
||||||
KeyStore keystore = KeyStore.getInstance("JKS");
|
|
||||||
|
|
||||||
keystore.load(fIn, storepass);
|
if (!usingHttps) {
|
||||||
Certificate cert = keystore.getCertificate(alias);
|
server = HttpServer.create(new InetSocketAddress(port), 10);
|
||||||
|
|
||||||
Log.info("Found Certificate: " + cert.getType());
|
|
||||||
|
|
||||||
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
|
|
||||||
keyManagerFactory.init(keystore, keypass);
|
|
||||||
|
|
||||||
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("SunX509");
|
|
||||||
trustManagerFactory.init(keystore);
|
|
||||||
|
|
||||||
server = HttpsServer.create(new InetSocketAddress(port), 10);
|
|
||||||
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
|
|
||||||
sslContext.init(keyManagerFactory.getKeyManagers(), null/*trustManagerFactory.getTrustManagers()*/, null);
|
|
||||||
|
|
||||||
((HttpsServer) server).setHttpsConfigurator(new HttpsConfigurator(sslContext) {
|
|
||||||
@Override
|
|
||||||
public void configure(HttpsParameters params) {
|
|
||||||
SSLEngine engine = sslContext.createSSLEngine();
|
|
||||||
|
|
||||||
params.setNeedClientAuth(false);
|
|
||||||
params.setCipherSuites(engine.getEnabledCipherSuites());
|
|
||||||
params.setProtocols(engine.getEnabledProtocols());
|
|
||||||
|
|
||||||
SSLParameters defaultSSLParameters = sslContext.getDefaultSSLParameters();
|
|
||||||
params.setSSLParameters(defaultSSLParameters);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
startSuccessful = true;
|
|
||||||
} catch (KeyManagementException | NoSuchAlgorithmException e) {
|
|
||||||
Log.error("WebServer: SSL Context Initialization Failed.");
|
|
||||||
Log.toLog(this.getClass().getName(), e);
|
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
Log.error("!--------!---------!---------!");
|
|
||||||
Log.error("WebServer: SSL Certificate KeyStore File not Found: " + keyStorePath);
|
|
||||||
Log.error("!--------!---------!---------!");
|
|
||||||
} catch (KeyStoreException | CertificateException | UnrecoverableKeyException e) {
|
|
||||||
Log.error("WebServer: SSL Certificate loading Failed.");
|
|
||||||
Log.toLog(this.getClass().getName(), e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.debug("Start Successful: " + startSuccessful);
|
server.createContext("/", new HttpHandler() {
|
||||||
|
|
||||||
if (!startSuccessful) {
|
|
||||||
return; // TODO Http Server
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.debug("Create server context");
|
|
||||||
HttpContext context = server.createContext("/", new HttpHandler() {
|
|
||||||
@Override
|
@Override
|
||||||
public void handle(HttpExchange xghng) throws IOException {
|
public void handle(HttpExchange exchange) throws IOException {
|
||||||
HttpsExchange exchange = (HttpsExchange) xghng;
|
OutputStream os = null;
|
||||||
try {
|
try {
|
||||||
URI uri = exchange.getRequestURI();
|
URI uri = exchange.getRequestURI();
|
||||||
String target = uri.toString();
|
String target = uri.toString();
|
||||||
Response response = getResponse(target);
|
|
||||||
|
WebUser user = null;
|
||||||
|
if (usingHttps) {
|
||||||
|
user = getUser(exchange.getRequestHeaders());
|
||||||
|
|
||||||
|
// Prompt authorization
|
||||||
|
if (user == null) {
|
||||||
|
Headers responseHeaders = exchange.getResponseHeaders();
|
||||||
|
responseHeaders.set("WWW-Authenticate", "Basic realm=\"/\";");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Response response = getResponse(target, user);
|
||||||
|
|
||||||
String content = response.getContent();
|
String content = response.getContent();
|
||||||
exchange.sendResponseHeaders(response.getCode(), content.length());
|
exchange.sendResponseHeaders(response.getCode(), content.length());
|
||||||
|
try (BufferedOutputStream out = new BufferedOutputStream(exchange.getResponseBody())) {
|
||||||
OutputStream os = exchange.getResponseBody();
|
try (ByteArrayInputStream bis = new ByteArrayInputStream(content.getBytes())) {
|
||||||
os.write(content.getBytes());
|
byte[] buffer = new byte[2048];
|
||||||
os.close();
|
int count;
|
||||||
|
while ((count = bis.read(buffer)) != -1) {
|
||||||
|
out.write(buffer, 0, count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.toLog(this.getClass().getName(), e);
|
Log.toLog(this.getClass().getName(), e);
|
||||||
throw e;
|
throw e;
|
||||||
|
} finally {
|
||||||
|
MiscUtils.close(os);
|
||||||
|
exchange.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -150,6 +123,7 @@ public class WebServer {
|
|||||||
server.setExecutor(new ThreadPoolExecutor(4, 8, 30, TimeUnit.SECONDS, new ArrayBlockingQueue<>(100)));
|
server.setExecutor(new ThreadPoolExecutor(4, 8, 30, TimeUnit.SECONDS, new ArrayBlockingQueue<>(100)));
|
||||||
|
|
||||||
server.start();
|
server.start();
|
||||||
|
|
||||||
enabled = true;
|
enabled = true;
|
||||||
|
|
||||||
Log.info(Phrase.WEBSERVER_RUNNING.parse(String.valueOf(server.getAddress().getPort())));
|
Log.info(Phrase.WEBSERVER_RUNNING.parse(String.valueOf(server.getAddress().getPort())));
|
||||||
@ -159,68 +133,192 @@ public class WebServer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (!request.hasAuthorization()) {
|
private WebUser getUser(Headers requestHeaders) {
|
||||||
// return new PromptAuthorizationResponse(output);
|
try {
|
||||||
// }
|
List<String> authorization = requestHeaders.get("Authorization");
|
||||||
// try {
|
if (Verify.isEmpty(authorization)) {
|
||||||
// if (!isAuthorized(request)) {
|
return null;
|
||||||
// ForbiddenResponse response403 = new ForbiddenResponse(output);
|
}
|
||||||
// String content = "<h1>403 Forbidden - Access Denied</h1>"
|
String auth = authorization.get(0);
|
||||||
// + "<p>Unauthorized User.<br>"
|
if (auth.contains("Basic ")) {
|
||||||
// + "Make sure your user has the correct access level.<br>"
|
auth = auth.split(" ")[1];
|
||||||
// + "You can use /plan web check <username> to check the permission level.</p>";
|
} else {
|
||||||
// response403.setContent(content);
|
throw new IllegalArgumentException("Wrong format of Auth");
|
||||||
// return response403;
|
}
|
||||||
// }
|
Base64.Decoder decoder = Base64.getDecoder();
|
||||||
|
byte[] decoded = decoder.decode(auth);
|
||||||
|
String[] userInfo = new String(decoded).split(":");
|
||||||
|
if (userInfo.length != 2) {
|
||||||
|
throw new IllegalArgumentException("User and Password not specified");
|
||||||
|
}
|
||||||
|
String user = userInfo[0];
|
||||||
|
String passwordRaw = userInfo[1];
|
||||||
|
|
||||||
private Response getResponse(String target) {
|
SecurityTable securityTable = plugin.getDB().getSecurityTable();
|
||||||
|
if (!securityTable.userExists(user)) {
|
||||||
|
throw new IllegalArgumentException("User Doesn't exist");
|
||||||
|
}
|
||||||
|
|
||||||
|
WebUser webUser = securityTable.getSecurityInfo(user);
|
||||||
|
|
||||||
|
boolean correctPass = PassEncryptUtil.verifyPassword(passwordRaw, webUser.getSaltedPassHash());
|
||||||
|
if (!correctPass) {
|
||||||
|
throw new IllegalArgumentException("User and Password do not match");
|
||||||
|
}
|
||||||
|
return webUser;
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
Log.debug("WebServer: " + e.getMessage());
|
||||||
|
return null;
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.toLog(this.getClass().getName(), e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean startHttpsServer() throws IOException {
|
||||||
|
String keyStorePath = Settings.WEBSERVER_CERTIFICATE_PATH.toString();
|
||||||
|
if (!keyStorePath.contains(":")) {
|
||||||
|
keyStorePath = plugin.getDataFolder() + keyStorePath;
|
||||||
|
}
|
||||||
|
char[] storepass = Settings.WEBSERVER_CERTIFICATE_STOREPASS.toString().toCharArray();
|
||||||
|
char[] keypass = Settings.WEBSERVER_CERTIFICATE_KEYPASS.toString().toCharArray();
|
||||||
|
String alias = Settings.WEBSERVER_CERTIFICATE_ALIAS.toString();
|
||||||
|
|
||||||
|
boolean startSuccessful = false;
|
||||||
|
try (FileInputStream fIn = new FileInputStream(keyStorePath)) {
|
||||||
|
KeyStore keystore = KeyStore.getInstance("JKS");
|
||||||
|
|
||||||
|
keystore.load(fIn, storepass);
|
||||||
|
Certificate cert = keystore.getCertificate(alias);
|
||||||
|
|
||||||
|
Log.info("Found Certificate: " + cert.getType());
|
||||||
|
|
||||||
|
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
|
||||||
|
keyManagerFactory.init(keystore, keypass);
|
||||||
|
|
||||||
|
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("SunX509");
|
||||||
|
trustManagerFactory.init(keystore);
|
||||||
|
|
||||||
|
server = HttpsServer.create(new InetSocketAddress(port), 10);
|
||||||
|
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
|
||||||
|
sslContext.init(keyManagerFactory.getKeyManagers(), null/*trustManagerFactory.getTrustManagers()*/, null);
|
||||||
|
|
||||||
|
((HttpsServer) server).setHttpsConfigurator(new HttpsConfigurator(sslContext) {
|
||||||
|
@Override
|
||||||
|
public void configure(HttpsParameters params) {
|
||||||
|
SSLEngine engine = sslContext.createSSLEngine();
|
||||||
|
|
||||||
|
params.setNeedClientAuth(false);
|
||||||
|
params.setCipherSuites(engine.getEnabledCipherSuites());
|
||||||
|
params.setProtocols(engine.getEnabledProtocols());
|
||||||
|
|
||||||
|
SSLParameters defaultSSLParameters = sslContext.getDefaultSSLParameters();
|
||||||
|
params.setSSLParameters(defaultSSLParameters);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
startSuccessful = true;
|
||||||
|
} catch (KeyManagementException | NoSuchAlgorithmException e) {
|
||||||
|
Log.error("WebServer: SSL Context Initialization Failed.");
|
||||||
|
Log.toLog(this.getClass().getName(), e);
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
Log.infoColor(ChatColor.YELLOW + "WebServer: SSL Certificate KeyStore File not Found: " + keyStorePath);
|
||||||
|
Log.info("No Certificate -> Using Http server for Visualization.");
|
||||||
|
Log.infoColor(ChatColor.YELLOW + "User Authorization Disabled! (Not possible over http)");
|
||||||
|
} catch (KeyStoreException | CertificateException | UnrecoverableKeyException e) {
|
||||||
|
Log.error("WebServer: SSL Certificate loading Failed.");
|
||||||
|
Log.toLog(this.getClass().getName(), e);
|
||||||
|
}
|
||||||
|
return startSuccessful;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Response getResponse(String target, WebUser user) {
|
||||||
|
if ("/favicon.ico".equals(target)) {
|
||||||
|
return new RedirectResponse("https://puu.sh/tK0KL/6aa2ba141b.ico");
|
||||||
|
}
|
||||||
|
if (usingHttps) {
|
||||||
|
if (user == null) {
|
||||||
|
return new PromptAuthorizationResponse();
|
||||||
|
}
|
||||||
|
|
||||||
|
int permLevel = user.getPermLevel(); // Lower number has higher clearance.
|
||||||
|
int required = getRequiredPermLevel(target, user.getName());
|
||||||
|
if (permLevel > required) {
|
||||||
|
return forbiddenResponse(permLevel, required);
|
||||||
|
}
|
||||||
|
}
|
||||||
String[] args = target.split("/");
|
String[] args = target.split("/");
|
||||||
if (args.length < 2) {
|
if (args.length < 2) {
|
||||||
return responseNotFound(null);
|
return rootPageResponse(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
String page = args[1];
|
String page = args[1];
|
||||||
switch (page) {
|
switch (page) {
|
||||||
case "favicon.ico":
|
|
||||||
return new RedirectResponse(null, "https://puu.sh/tK0KL/6aa2ba141b.ico");
|
|
||||||
case "players":
|
case "players":
|
||||||
return new PlayersPageResponse(null, plugin);
|
return new PlayersPageResponse(plugin);
|
||||||
case "player":
|
case "player":
|
||||||
return playerResponse(args, null);
|
return playerResponse(args);
|
||||||
case "server":
|
case "server":
|
||||||
return serverResponse(null);
|
return serverResponse();
|
||||||
default:
|
default:
|
||||||
return responseNotFound(null);
|
return notFoundResponse();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Response serverResponse(OutputStream output) {
|
private ForbiddenResponse forbiddenResponse(int permLevel, int required) {
|
||||||
|
ForbiddenResponse response403 = new ForbiddenResponse();
|
||||||
|
String content = "<h1>403 Forbidden - Access Denied</h1>"
|
||||||
|
+ "<p>Unauthorized User.<br>"
|
||||||
|
+ "Make sure your user has the correct access level.<br>"
|
||||||
|
+ "This page requires permission level of " + String.valueOf(required) + ",<br>"
|
||||||
|
+ "This user has permission level of " + String.valueOf(permLevel) + "</p>";
|
||||||
|
response403.setContent(content);
|
||||||
|
return response403;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Response rootPageResponse(WebUser user) {
|
||||||
|
if (user == null) {
|
||||||
|
return notFoundResponse();
|
||||||
|
}
|
||||||
|
switch (user.getPermLevel()) {
|
||||||
|
case 0:
|
||||||
|
return serverResponse();
|
||||||
|
case 1:
|
||||||
|
return new PlayersPageResponse(plugin);
|
||||||
|
case 2:
|
||||||
|
return playerResponse(new String[]{"", "", user.getName()});
|
||||||
|
default:
|
||||||
|
return forbiddenResponse(user.getPermLevel(), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Response serverResponse() {
|
||||||
if (!dataReqHandler.checkIfAnalysisIsCached()) {
|
if (!dataReqHandler.checkIfAnalysisIsCached()) {
|
||||||
return new NotFoundResponse(output, "Analysis data was not cached.");
|
return new NotFoundResponse("Analysis Data was not cached.<br>Use /plan analyze to cache the Data.");
|
||||||
}
|
}
|
||||||
return new AnalysisPageResponse(output, dataReqHandler);
|
return new AnalysisPageResponse(dataReqHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Response playerResponse(String[] args, OutputStream output) {
|
private Response playerResponse(String[] args) {
|
||||||
if (args.length < 3) {
|
if (args.length < 3) {
|
||||||
return new NotFoundResponse(output);
|
return new NotFoundResponse();
|
||||||
}
|
}
|
||||||
String playerName = args[2].trim();
|
String playerName = args[2].trim();
|
||||||
UUID uuid = UUIDUtility.getUUIDOf(playerName);
|
UUID uuid = UUIDUtility.getUUIDOf(playerName);
|
||||||
if (uuid == null) {
|
if (uuid == null) {
|
||||||
return new NotFoundResponse(output, "Player has no UUID");
|
return new NotFoundResponse("Player has no UUID");
|
||||||
}
|
}
|
||||||
if (!dataReqHandler.checkIfCached(uuid)) {
|
if (!dataReqHandler.checkIfCached(uuid)) {
|
||||||
return new NotFoundResponse(output, "Player's data was not cached.");
|
return new NotFoundResponse("Player's data was not cached.<br>Use /plan inspect " + playerName + " to cache the Data.");
|
||||||
}
|
}
|
||||||
return new InspectPageResponse(output, dataReqHandler, uuid);
|
return new InspectPageResponse(dataReqHandler, uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Response responseNotFound(OutputStream output) {
|
private Response notFoundResponse() {
|
||||||
NotFoundResponse response404 = new NotFoundResponse(output);
|
NotFoundResponse response404 = new NotFoundResponse();
|
||||||
String content = "<h1>404 Not Found</h1>"
|
String content = "<h1>404 Not Found</h1>"
|
||||||
+ "<p>Make sure you're accessing a link given by a command, Examples:</p>"
|
+ "<p>Make sure you're accessing a link given by a command, Examples:</p>"
|
||||||
+ "<p>" + HtmlUtils.getInspectUrl("<player>") + " or<br>"
|
+ "<p>" + getProtocol() + HtmlUtils.getInspectUrl("<player>") + " or<br>"
|
||||||
+ HtmlUtils.getServerAnalysisUrl() + "</p>";
|
+ getProtocol() + HtmlUtils.getServerAnalysisUrl() + "</p>";
|
||||||
response404.setContent(content);
|
response404.setContent(content);
|
||||||
return response404;
|
return response404;
|
||||||
}
|
}
|
||||||
@ -237,16 +335,58 @@ public class WebServer {
|
|||||||
*/
|
*/
|
||||||
public void stop() {
|
public void stop() {
|
||||||
Log.info(Phrase.WEBSERVER_CLOSE.toString());
|
Log.info(Phrase.WEBSERVER_CLOSE.toString());
|
||||||
shutdown = true;
|
|
||||||
if (server != null) {
|
if (server != null) {
|
||||||
server.stop(0);
|
server.stop(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Used to get the handler for Html content requests.
|
||||||
|
*
|
||||||
* @return DataRequestHandler used by the WebServer.
|
* @return DataRequestHandler used by the WebServer.
|
||||||
*/
|
*/
|
||||||
public DataRequestHandler getDataReqHandler() {
|
public DataRequestHandler getDataReqHandler() {
|
||||||
return dataReqHandler;
|
return dataReqHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int getRequiredPermLevel(String target, String user) {
|
||||||
|
String[] t = target.split("/");
|
||||||
|
if (t.length < 2) {
|
||||||
|
return 100;
|
||||||
|
}
|
||||||
|
if (t.length > 3) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
String page = t[1];
|
||||||
|
switch (page) {
|
||||||
|
case "players":
|
||||||
|
return 1;
|
||||||
|
case "player":
|
||||||
|
// /player/ - 404 for perm lvl 1
|
||||||
|
if (t.length < 3) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
final String wantedUser = t[2].toLowerCase().trim();
|
||||||
|
final String theUser = user.trim().toLowerCase();
|
||||||
|
if (wantedUser.equals(theUser)) {
|
||||||
|
return 2;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProtocol() {
|
||||||
|
return usingHttps ? "https" : "http";
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean usingHttps() {
|
||||||
|
return usingHttps;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAuthRequired() {
|
||||||
|
return usingHttps;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,16 +2,13 @@ package main.java.com.djrapitops.plan.ui.webserver.response;
|
|||||||
|
|
||||||
import main.java.com.djrapitops.plan.ui.html.DataRequestHandler;
|
import main.java.com.djrapitops.plan.ui.html.DataRequestHandler;
|
||||||
|
|
||||||
import java.io.OutputStream;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Rsl1122
|
* @author Rsl1122
|
||||||
* @since 3.5.2
|
* @since 3.5.2
|
||||||
*/
|
*/
|
||||||
public class AnalysisPageResponse extends Response {
|
public class AnalysisPageResponse extends Response {
|
||||||
|
|
||||||
public AnalysisPageResponse(OutputStream output, DataRequestHandler h) {
|
public AnalysisPageResponse(DataRequestHandler h) {
|
||||||
super(output);
|
|
||||||
super.setHeader("HTTP/1.1 200 OK");
|
super.setHeader("HTTP/1.1 200 OK");
|
||||||
super.setContent(h.getAnalysisHtml());
|
super.setContent(h.getAnalysisHtml());
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,12 @@
|
|||||||
package main.java.com.djrapitops.plan.ui.webserver.response;
|
package main.java.com.djrapitops.plan.ui.webserver.response;
|
||||||
|
|
||||||
import java.io.OutputStream;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Rsl1122
|
* @author Rsl1122
|
||||||
* @since 3.5.2
|
* @since 3.5.2
|
||||||
*/
|
*/
|
||||||
public class ForbiddenResponse extends Response {
|
public class ForbiddenResponse extends Response {
|
||||||
|
|
||||||
public ForbiddenResponse(OutputStream output) {
|
public ForbiddenResponse() {
|
||||||
super(output);
|
|
||||||
super.setHeader("HTTP/1.1 403 Forbidden");
|
super.setHeader("HTTP/1.1 403 Forbidden");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@ package main.java.com.djrapitops.plan.ui.webserver.response;
|
|||||||
|
|
||||||
import main.java.com.djrapitops.plan.ui.html.DataRequestHandler;
|
import main.java.com.djrapitops.plan.ui.html.DataRequestHandler;
|
||||||
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -11,8 +10,7 @@ import java.util.UUID;
|
|||||||
*/
|
*/
|
||||||
public class InspectPageResponse extends Response {
|
public class InspectPageResponse extends Response {
|
||||||
|
|
||||||
public InspectPageResponse(OutputStream output, DataRequestHandler h, UUID uuid) {
|
public InspectPageResponse(DataRequestHandler h, UUID uuid) {
|
||||||
super(output);
|
|
||||||
super.setHeader("HTTP/1.1 200 OK");
|
super.setHeader("HTTP/1.1 200 OK");
|
||||||
super.setContent(h.getInspectHtml(uuid));
|
super.setContent(h.getInspectHtml(uuid));
|
||||||
}
|
}
|
||||||
|
@ -2,16 +2,13 @@ package main.java.com.djrapitops.plan.ui.webserver.response;
|
|||||||
|
|
||||||
import main.java.com.djrapitops.plan.ui.html.Html;
|
import main.java.com.djrapitops.plan.ui.html.Html;
|
||||||
|
|
||||||
import java.io.OutputStream;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Rsl1122
|
* @author Rsl1122
|
||||||
* @since 3.5.2
|
* @since 3.5.2
|
||||||
*/
|
*/
|
||||||
public class InternalErrorResponse extends Response {
|
public class InternalErrorResponse extends Response {
|
||||||
|
|
||||||
public InternalErrorResponse(OutputStream output, Throwable e, String cause) {
|
public InternalErrorResponse(Throwable e, String cause) {
|
||||||
super(output);
|
|
||||||
super.setHeader("HTTP/1.1 500 Internal Error");
|
super.setHeader("HTTP/1.1 500 Internal Error");
|
||||||
StringBuilder content = new StringBuilder();
|
StringBuilder content = new StringBuilder();
|
||||||
content.append("<h1>500 Internal Error occurred</h1>");
|
content.append("<h1>500 Internal Error occurred</h1>");
|
||||||
|
@ -4,7 +4,6 @@ import main.java.com.djrapitops.plan.Log;
|
|||||||
import main.java.com.djrapitops.plan.utilities.HtmlUtils;
|
import main.java.com.djrapitops.plan.utilities.HtmlUtils;
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.OutputStream;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Rsl1122
|
* @author Rsl1122
|
||||||
@ -12,8 +11,7 @@ import java.io.OutputStream;
|
|||||||
*/
|
*/
|
||||||
public class JavaScriptResponse extends Response {
|
public class JavaScriptResponse extends Response {
|
||||||
|
|
||||||
public JavaScriptResponse(OutputStream output, String resource) {
|
public JavaScriptResponse(String resource) {
|
||||||
super(output);
|
|
||||||
super.setHeader("HTTP/1.1 200 OK");
|
super.setHeader("HTTP/1.1 200 OK");
|
||||||
try {
|
try {
|
||||||
super.setContent(HtmlUtils.getStringFromResource(resource));
|
super.setContent(HtmlUtils.getStringFromResource(resource));
|
||||||
|
@ -1,21 +1,17 @@
|
|||||||
package main.java.com.djrapitops.plan.ui.webserver.response;
|
package main.java.com.djrapitops.plan.ui.webserver.response;
|
||||||
|
|
||||||
import java.io.OutputStream;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Rsl1122
|
* @author Rsl1122
|
||||||
* @since 3.5.2
|
* @since 3.5.2
|
||||||
*/
|
*/
|
||||||
public class NotFoundResponse extends Response {
|
public class NotFoundResponse extends Response {
|
||||||
|
|
||||||
public NotFoundResponse(OutputStream output) {
|
public NotFoundResponse() {
|
||||||
super(output);
|
|
||||||
super.setHeader("HTTP/1.1 404 Not Found");
|
super.setHeader("HTTP/1.1 404 Not Found");
|
||||||
super.setContent("<h1>404 Not Found</h1><p>Page does not exist.</p>");
|
super.setContent("<h1>404 Not Found</h1><p>Page does not exist.</p>");
|
||||||
}
|
}
|
||||||
|
|
||||||
public NotFoundResponse(OutputStream output, String msg) {
|
public NotFoundResponse(String msg) {
|
||||||
super(output);
|
|
||||||
super.setHeader("HTTP/1.1 404 Not Found");
|
super.setHeader("HTTP/1.1 404 Not Found");
|
||||||
super.setContent("<h1>404 Not Found</h1><p>" + msg + "</p>");
|
super.setContent("<h1>404 Not Found</h1><p>" + msg + "</p>");
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@ import main.java.com.djrapitops.plan.ui.html.Html;
|
|||||||
import main.java.com.djrapitops.plan.utilities.HtmlUtils;
|
import main.java.com.djrapitops.plan.utilities.HtmlUtils;
|
||||||
import main.java.com.djrapitops.plan.utilities.comparators.UserDataNameComparator;
|
import main.java.com.djrapitops.plan.utilities.comparators.UserDataNameComparator;
|
||||||
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -15,14 +14,13 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public class PlayersPageResponse extends Response {
|
public class PlayersPageResponse extends Response {
|
||||||
|
|
||||||
public PlayersPageResponse(OutputStream output, Plan plugin) {
|
public PlayersPageResponse(Plan plugin) {
|
||||||
super(output);
|
|
||||||
super.setHeader("HTTP/1.1 200 OK");
|
super.setHeader("HTTP/1.1 200 OK");
|
||||||
super.setContent(buildContent(plugin.getInspectCache().getCachedUserData()));
|
super.setContent(buildContent(plugin.getInspectCache().getCachedUserData()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String buildContent(List<UserData> cached) {
|
public static String buildContent(List<UserData> cached) {
|
||||||
StringBuilder html = new StringBuilder("<h1>Cached Players</h1><p>");
|
StringBuilder html = new StringBuilder("<!DOCTYPE html><html><body><h1>Cached Players</h1><p>");
|
||||||
|
|
||||||
int size = cached.size();
|
int size = cached.size();
|
||||||
html.append(size)
|
html.append(size)
|
||||||
@ -39,7 +37,7 @@ public class PlayersPageResponse extends Response {
|
|||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
html.append("</tr></table>");
|
html.append("</tr></table></body></html>");
|
||||||
return html.toString();
|
return html.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,14 @@
|
|||||||
package main.java.com.djrapitops.plan.ui.webserver.response;
|
package main.java.com.djrapitops.plan.ui.webserver.response;
|
||||||
|
|
||||||
import java.io.OutputStream;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Rsl1122
|
* @author Rsl1122
|
||||||
* @since 3.5.2
|
* @since 3.5.2
|
||||||
*/
|
*/
|
||||||
public class PromptAuthorizationResponse extends Response {
|
public class PromptAuthorizationResponse extends Response {
|
||||||
|
|
||||||
public PromptAuthorizationResponse(OutputStream output) {
|
public PromptAuthorizationResponse() {
|
||||||
super(output);
|
|
||||||
super.setHeader("HTTP/1.1 401 Access Denied\r\n"
|
super.setHeader("HTTP/1.1 401 Access Denied\r\n"
|
||||||
+ "WWW-Authenticate: Basic realm=\"Analysis\";");
|
+ "WWW-Authenticate: Basic realm=\"/\";");
|
||||||
super.setContent("<h1>401 Unauthorized</h1><p>Authentication Failed.<br>"
|
super.setContent("<h1>401 Unauthorized</h1><p>Authentication Failed.<br>"
|
||||||
+ "- Ensure you have registered a user with <b>/plan register</b><br>"
|
+ "- Ensure you have registered a user with <b>/plan register</b><br>"
|
||||||
+ "- Check that the username and password are correct<br>"
|
+ "- Check that the username and password are correct<br>"
|
||||||
|
@ -1,15 +1,12 @@
|
|||||||
package main.java.com.djrapitops.plan.ui.webserver.response;
|
package main.java.com.djrapitops.plan.ui.webserver.response;
|
||||||
|
|
||||||
import java.io.OutputStream;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Rsl1122
|
* @author Rsl1122
|
||||||
* @since 3.5.2
|
* @since 3.5.2
|
||||||
*/
|
*/
|
||||||
public class RedirectResponse extends Response {
|
public class RedirectResponse extends Response {
|
||||||
|
|
||||||
public RedirectResponse(OutputStream output, String direct) {
|
public RedirectResponse(String direct) {
|
||||||
super(output);
|
|
||||||
super.setHeader("HTTP/1.1 302 Found");
|
super.setHeader("HTTP/1.1 302 Found");
|
||||||
super.setContent("Location: " + direct);
|
super.setContent("Location: " + direct);
|
||||||
}
|
}
|
||||||
|
@ -1,39 +1,18 @@
|
|||||||
package main.java.com.djrapitops.plan.ui.webserver.response;
|
package main.java.com.djrapitops.plan.ui.webserver.response;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Rsl1122
|
* @author Rsl1122
|
||||||
* @since 3.5.2
|
* @since 3.5.2
|
||||||
*/
|
*/
|
||||||
public abstract class Response {
|
public abstract class Response {
|
||||||
|
|
||||||
|
|
||||||
private final OutputStream output;
|
|
||||||
|
|
||||||
private String header;
|
private String header;
|
||||||
private String content;
|
private String content;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class Constructor.
|
* Class Constructor.
|
||||||
*
|
|
||||||
* @param output Website OutputStream to write the response to.
|
|
||||||
*/
|
*/
|
||||||
public Response(OutputStream output) {
|
public Response() {
|
||||||
this.output = output;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Writes the HTML to the OutputStream according to the requested page.
|
|
||||||
*
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
public void sendStaticResource() throws IOException {
|
|
||||||
String response = getResponse();
|
|
||||||
// Log.debug("Response: " + response); // Responses should not be logged, html content large.
|
|
||||||
output.write(response.getBytes());
|
|
||||||
output.flush();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getResponse() {
|
public String getResponse() {
|
||||||
|
@ -3,6 +3,7 @@ package main.java.com.djrapitops.plan.utilities;
|
|||||||
import main.java.com.djrapitops.plan.Plan;
|
import main.java.com.djrapitops.plan.Plan;
|
||||||
import main.java.com.djrapitops.plan.Settings;
|
import main.java.com.djrapitops.plan.Settings;
|
||||||
import main.java.com.djrapitops.plan.ui.html.Html;
|
import main.java.com.djrapitops.plan.ui.html.Html;
|
||||||
|
import main.java.com.djrapitops.plan.ui.webserver.WebServer;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
@ -73,28 +74,44 @@ public class HtmlUtils {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static String getServerAnalysisUrlWithProtocol() {
|
public static String getServerAnalysisUrlWithProtocol() {
|
||||||
return Settings.LINK_PROTOCOL.toString() + ":" + getServerAnalysisUrl();
|
return getProtocol() + ":" + getServerAnalysisUrl();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static String getServerAnalysisUrl() {
|
public static String getServerAnalysisUrl() {
|
||||||
int port = Settings.WEBSERVER_PORT.getNumber();
|
String ip = getIP();
|
||||||
String ip = Plan.getInstance().getVariable().getIp() + ":" + port;
|
|
||||||
boolean useAlternativeIP = Settings.SHOW_ALTERNATIVE_IP.isTrue();
|
|
||||||
if (useAlternativeIP) {
|
|
||||||
ip = Settings.ALTERNATIVE_IP.toString().replace("%port%", String.valueOf(port));
|
|
||||||
}
|
|
||||||
return "//" + ip + "/server";
|
return "//" + ip + "/server";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to get the WebServer's IP with Port.
|
||||||
|
*
|
||||||
|
* @return For example 127.0.0.1:8804
|
||||||
|
*/
|
||||||
|
public static String getIP() {
|
||||||
|
int port = Settings.WEBSERVER_PORT.getNumber();
|
||||||
|
String ip;
|
||||||
|
if (Settings.SHOW_ALTERNATIVE_IP.isTrue()) {
|
||||||
|
ip = Settings.ALTERNATIVE_IP.toString().replace("%port%", String.valueOf(port));
|
||||||
|
} else {
|
||||||
|
ip = Plan.getInstance().getVariable().getIp() + ":" + port;
|
||||||
|
}
|
||||||
|
return ip;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getProtocol() {
|
||||||
|
WebServer uiServer = Plan.getInstance().getUiServer();
|
||||||
|
return uiServer.isEnabled() ? uiServer.getProtocol() : Settings.LINK_PROTOCOL.toString();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param playerName
|
* @param playerName
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static String getInspectUrlWithProtocol(String playerName) {
|
public static String getInspectUrlWithProtocol(String playerName) {
|
||||||
return Settings.LINK_PROTOCOL.toString() + ":" + getInspectUrl(playerName);
|
return getProtocol() + ":" + getInspectUrl(playerName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -102,12 +119,7 @@ public class HtmlUtils {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static String getInspectUrl(String playerName) {
|
public static String getInspectUrl(String playerName) {
|
||||||
int port = Settings.WEBSERVER_PORT.getNumber();
|
String ip = getIP();
|
||||||
String ip = Plan.getInstance().getVariable().getIp() + ":" + port;
|
|
||||||
boolean useAlternativeIP = Settings.SHOW_ALTERNATIVE_IP.isTrue();
|
|
||||||
if (useAlternativeIP) {
|
|
||||||
ip = Settings.ALTERNATIVE_IP.toString().replace("%port%", String.valueOf(port));
|
|
||||||
}
|
|
||||||
return "//" + ip + "/player/" + playerName;
|
return "//" + ip + "/player/" + playerName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ Settings:
|
|||||||
InternalIP: 0.0.0.0
|
InternalIP: 0.0.0.0
|
||||||
ShowAlternativeServerIP: false
|
ShowAlternativeServerIP: false
|
||||||
AlternativeIP: your.ip.here:%port%
|
AlternativeIP: your.ip.here:%port%
|
||||||
LinkProtocol: http
|
ExternalWebServerLinkProtocol: http
|
||||||
Security:
|
Security:
|
||||||
DisplayIPsAndUUIDs: true
|
DisplayIPsAndUUIDs: true
|
||||||
Certificate:
|
Certificate:
|
||||||
|
Loading…
Reference in New Issue
Block a user