Skip to content

Commit

Permalink
- Added some more security logging
Browse files Browse the repository at this point in the history
- changed server time to be HH:mm:ss.
- Changed all JS alerts over to html+css alerts, some of whom are dismissible.
  • Loading branch information
dries007 committed Jul 22, 2017
1 parent e0a7cdc commit 1094418
Show file tree
Hide file tree
Showing 26 changed files with 298 additions and 264 deletions.
4 changes: 2 additions & 2 deletions build.gradle
Expand Up @@ -16,7 +16,7 @@ apply plugin: "idea-utils"
archivesBaseName = "D3Backend"
group = "net.doubledoordev.backend"

version = "0.11.1"
version = "0.11.2"
if (System.getenv().BUILD_NUMBER != null) version += "." + System.getenv().BUILD_NUMBER

def vendor = "DoubleDoorDevelopment"
Expand Down Expand Up @@ -66,7 +66,7 @@ dependencies {
compile group: "org.apache.commons", name: "commons-io", version: "1.3.2"
compile group: "org.apache.commons", name: "commons-lang3", version: "3.3.2"
compile group: "commons-codec", name: "commons-codec", version: "1.9"
compile group: "org.freemarker", name: "freemarker", version: "2.3.20"
compile group: "org.freemarker", name: "freemarker", version: "2.3.23"
compile group: "org.apache.logging.log4j", name: "log4j-core", version: "2.0.2"
compile group: "net.lingala.zip4j", name: "zip4j", version: "1.3.2"
compile group: "org.glassfish.grizzly", name: "grizzly-http-all", version: "2.3.17"
Expand Down
Expand Up @@ -112,8 +112,7 @@ public Collection<File> makeBreadcrumbs()

public String stripServer(File file)
{
if (file.equals(serverFolder)) return serverFolder.getName();
return file.toString().substring(serverFolder.toString().length() + 1).replace('\\', '/');
return Helper.getRelativeString(serverFolder, file);
}

public static boolean canEdit(File file)
Expand Down Expand Up @@ -252,7 +251,7 @@ public void delete(IMethodCaller caller) throws IOException

public void newFile(IMethodCaller caller, String name) throws IOException
{
server.logAction(caller, "New File " + stripServer(file));
server.logAction(caller, "New File " + name + " in " + stripServer(file));
FileUtils.touch(new File(file, name));
FileMonitorSocketApplication.update(getJson(file), file);
}
Expand Down
35 changes: 16 additions & 19 deletions src/main/java/net/doubledoordev/backend/util/Cache.java
Expand Up @@ -59,7 +59,7 @@ public class Cache
*/
private static final Timer TIMER = new Timer("Cache-Timer", true);

private static final Table<String, String, ForgeBuild> FORGE_VERSION_TABLE = Tables.newCustomTable(new LinkedHashMap<>(), LinkedHashMap::new);
private static final Table<String, String, ForgeBuild> FORGE_VERSION_TABLE = Tables.synchronizedTable(Tables.newCustomTable(new LinkedHashMap<>(), LinkedHashMap::new));
private static final TimerTask FORGE_VERSIONS_DOWNLOADER = new TimerTask()
{
private boolean hasInstaller(JsonObject object)
Expand All @@ -78,7 +78,7 @@ public void run()
Main.LOGGER.info("[Cache] Refreshing Forge version cache....");

Reader reader = new InputStreamReader(new URL(FORGE_VERIONS_URL).openStream());
JsonObject root = Constants.JSONPARSER.parse(reader).getAsJsonObject();
JsonObject root = JSONPARSER.parse(reader).getAsJsonObject();
reader.close();

// WARNING: Java 8 madness ahead.
Expand Down Expand Up @@ -127,7 +127,7 @@ public void run()
}
}
};
private static final Map<String, URL> CASHED_MC_VERSIONS = new LinkedHashMap<>();
private static final Map<String, URL> CASHED_MC_VERSIONS = Collections.synchronizedMap(new LinkedHashMap<>());
private static final TimerTask MC_VERSIONS_DOWNLOADER = new TimerTask()
{
@Override
Expand All @@ -136,31 +136,28 @@ public void run()
JsonObject versionList;
try
{
Reader sr = new InputStreamReader(new URL(Constants.MC_VERIONS_URL).openStream());
versionList = Constants.JSONPARSER.parse(sr).getAsJsonObject();
Reader sr = new InputStreamReader(new URL(MC_VERIONS_URL).openStream());
versionList = JSONPARSER.parse(sr).getAsJsonObject();
sr.close();
}
catch (IOException e)
{
e.printStackTrace();
return;
}
synchronized (CASHED_MC_VERSIONS)
CASHED_MC_VERSIONS.clear();
for (JsonElement element : versionList.getAsJsonArray("versions"))
{
CASHED_MC_VERSIONS.clear();
for (JsonElement element : versionList.getAsJsonArray("versions"))
JsonObject o = element.getAsJsonObject();
if (!o.get("type").getAsString().equals("release") && !o.get("type").getAsString().equals("snapshot"))
continue;
try
{
JsonObject o = element.getAsJsonObject();
if (!o.get("type").getAsString().equals("release") && !o.get("type").getAsString().equals("snapshot"))
continue;
try
{
CASHED_MC_VERSIONS.put(o.get("id").getAsString(), new URL(o.get("url").getAsString()));
}
catch (MalformedURLException e)
{
e.printStackTrace();
}
CASHED_MC_VERSIONS.put(o.get("id").getAsString(), new URL(o.get("url").getAsString()));
}
catch (MalformedURLException e)
{
e.printStackTrace();
}
}
}
Expand Down
15 changes: 13 additions & 2 deletions src/main/java/net/doubledoordev/backend/util/Helper.java
Expand Up @@ -55,6 +55,7 @@ public class Helper
private static final Map<String, String> UUID_USERNMAME_MAP = new HashMap<>();
private static final SimpleDateFormat BAN_SIMPLE_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
private static final SimpleDateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
private static final SimpleDateFormat HTML_TIME_FORMAT = new SimpleDateFormat("'<b>'HH:mm'</b>':ss");
public static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("#.##");
private static final char[] symbols = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
private static final int MAX_REDIRECTS = 25;
Expand Down Expand Up @@ -331,15 +332,19 @@ public static IMethodCaller invokeWithRefectionMagic(WebSocket caller, Object in

public static String getVersionString()
{
return String.format("v%s - build #%s", Main.version, Main.build);
return Main.version;
}

public static String formatDate(long time)
{
if (time == -1) time = new Date().getTime();
return SIMPLE_DATE_FORMAT.format(time);
}

public static String getServerTime()
{
return HTML_TIME_FORMAT.format(new Date());
}

public static String stripColor(String txt)
{
return txt.replaceAll("(?i)\u00a7[0-9a-fk-or]", "");
Expand Down Expand Up @@ -394,4 +399,10 @@ public static void doWebMethodCall(WebSocket socket, String text, Object o)
socket.close();
}
}

public static String getRelativeString(File root, File target)
{
if (root.equals(target)) return ".";
return target.toString().substring(root.toString().length() + 1).replace('\\', '/');
}
}
Expand Up @@ -19,7 +19,7 @@
package net.doubledoordev.backend.web.http;

import com.google.common.collect.ImmutableList;
import freemarker.ext.beans.BeansWrapper;
import freemarker.ext.beans.BeansWrapperBuilder;
import freemarker.template.*;
import net.doubledoordev.backend.Main;
import net.doubledoordev.backend.permissions.User;
Expand Down Expand Up @@ -56,19 +56,20 @@ public class FreemarkerHandler extends StaticHttpHandlerBase implements ErrorPag
{
public static final ImmutableList<String> ADMINPAGES = ImmutableList.of("console", "backendConsoleText");
public static long lastRequest = 0L;
public final Configuration freemarker = new Configuration();
public final Configuration freemarker = new Configuration(Configuration.VERSION_2_3_0);

public FreemarkerHandler(Class clazz, String path) throws TemplateModelException
{
freemarker.setClassForTemplateLoading(clazz, path);
freemarker.setObjectWrapper(new DefaultObjectWrapper());
freemarker.setObjectWrapper(new DefaultObjectWrapper(Configuration.VERSION_2_3_0));
freemarker.setDefaultEncoding("UTF-8");
freemarker.setTemplateExceptionHandler(TemplateExceptionHandler.HTML_DEBUG_HANDLER);
freemarker.setIncompatibleImprovements(new Version(2, 3, 20)); // FreeMarker 2.3.20
Map<String, Object> dataObject = new HashMap<>();
dataObject.put("Settings", Settings.SETTINGS);
dataObject.put("Helper", BeansWrapper.getDefaultInstance().getStaticModels().get(Helper.class.getName()));
freemarker.setAllSharedVariables(new SimpleHash(dataObject));

dataObject.put("Helper", new BeansWrapperBuilder(Configuration.VERSION_2_3_0).build().getStaticModels().get(Helper.class.getName()));
freemarker.setAllSharedVariables(new SimpleHash(dataObject, new DefaultObjectWrapperBuilder(Configuration.VERSION_2_3_0).build()));

if (!Main.debug) freemarker.setTemplateUpdateDelay(0);
}
Expand Down
Expand Up @@ -29,6 +29,7 @@
import net.doubledoordev.backend.util.Settings;
import net.doubledoordev.backend.util.exceptions.OutOfPortsException;
import net.doubledoordev.backend.util.exceptions.PostException;
import net.doubledoordev.backend.util.methodCaller.IMethodCaller;
import net.doubledoordev.backend.util.methodCaller.UserMethodCaller;
import org.glassfish.grizzly.EmptyCompletionHandler;
import org.glassfish.grizzly.http.multipart.MultipartScanner;
Expand Down Expand Up @@ -115,14 +116,14 @@ private String doServer(final HashMap<String, Object> data, final String uri, fi
final Server server = Settings.getServerByName(request.getParameter(SERVER));
if (server == null || !server.canUserControl(user)) throw new PostException("Server doesn't exist or user doesn't have permission to edit the server.");
data.put(SERVER, server);
upload(server.getFolder(), request, data, uri, response);
upload(new UserMethodCaller(user), server, server.getFolder(), request, data, uri, response);
return null;
}

private void upload(File folder, Request request, HashMap<String, Object> data, String uri, Response response)
private void upload(IMethodCaller caller, Server server, File folder, Request request, HashMap<String, Object> data, String uri, Response response)
{
response.suspend();
final UploaderMultipartHandler uploader = new UploaderMultipartHandler(folder);
final UploaderMultipartHandler uploader = new UploaderMultipartHandler(caller, server, folder);
MultipartScanner.scan(request, uploader, new EmptyCompletionHandler<Request>()
{
@Override
Expand Down Expand Up @@ -154,7 +155,7 @@ public void completed(final Request newRequest)
@Override
public void failed(Throwable throwable)
{
Main.LOGGER.warn("Upload failed to {}", folder.getAbsolutePath());
Main.LOGGER.warn("Upload failed to {}", server.getFolder());
throwable.printStackTrace();
response.resume();
}
Expand All @@ -171,7 +172,7 @@ private String doFilemanager(final HashMap<String, Object> data, final String ur
data.put(SERVER, server);
final FileManager fileManager = new FileManager(server, request.getParameter(FILE));
data.put("fm", fileManager);
upload(fileManager.getFile(), request, data, uri, response);
upload(new UserMethodCaller(user), server, fileManager.getFile(), request, data, uri, response);
return null;
}

Expand Down
Expand Up @@ -18,6 +18,9 @@

package net.doubledoordev.backend.web.http;

import net.doubledoordev.backend.server.Server;
import net.doubledoordev.backend.util.Helper;
import net.doubledoordev.backend.util.methodCaller.IMethodCaller;
import org.glassfish.grizzly.ReadHandler;
import org.glassfish.grizzly.http.io.NIOInputStream;
import org.glassfish.grizzly.http.multipart.ContentDisposition;
Expand All @@ -35,10 +38,14 @@
public class UploaderMultipartHandler implements MultipartEntryHandler
{
private static final String FILENAME_ENTRY = "fileName";
private final IMethodCaller caller;
private final Server server;
private final File folder;

public UploaderMultipartHandler(File folder)
public UploaderMultipartHandler(IMethodCaller caller, Server server, File folder)
{
this.caller = caller;
this.server = server;
this.folder = folder;
}

Expand All @@ -54,6 +61,8 @@ public void handle(final MultipartEntry multipartEntry) throws Exception
final String filename = contentDisposition.getDispositionParamUnquoted("filename");
final NIOInputStream inputStream = multipartEntry.getNIOInputStream();

server.logAction(caller, "Uploading file " + filename + " to " + Helper.getRelativeString(server.getFolder(), folder));

// start asynchronous non-blocking content read.
inputStream.notifyAvailable(new UploadReadHandler(new File(folder, filename), inputStream));
}
Expand Down
12 changes: 6 additions & 6 deletions src/main/resources/templates/advancedsettings.ftl
Expand Up @@ -40,7 +40,7 @@
<label for="RestartingInfo_restartScheduleMessage">Reboot schedule time</label>

<div class="input-group">
<input id="RestartingInfo_restartScheduleMessage" class="form-control" aria-describedby="helpBlock" type="text" placeholder="00:00">
<input id="RestartingInfo_restartScheduleMessage" class="form-control" aria-describedby="helpBlock" placeholder="00:00" maxlength="100">

<div class="input-group-addon">%time = time left in min</div>
</div>
Expand Down Expand Up @@ -115,7 +115,7 @@
if (typeof allkeys[key1] === "undefined") allkeys[key1] = [];
allkeys[key1].push(key2);
}
var dom = document.getElementById(key1 + "_" + key2);
var dom = get(key1 + "_" + key2);
if (dom != null)
{
if (dom.type === "checkbox")
Expand All @@ -142,16 +142,16 @@
}
else
{
alert(temp.message);
addAlert(temp.message, true);
}
};
websocket.onerror = function (evt)
{
alert("The websocket errored. Refresh the page!")
addAlert("The websocket errored. Refresh the page!")
};
websocket.onclose = function (evt)
{
alert("The websocket closed. Refresh the page!")
addAlert("The websocket closed. Refresh the page!")
};
function send(key1)
Expand All @@ -161,7 +161,7 @@
for (key2 in allkeys[key1])
{
var name = key1 + "_" + allkeys[key1][key2];
var dom = document.getElementById(name);
var dom = get(name);
if (dom == null) continue;
if (dom.type === "checkbox")
{
Expand Down
6 changes: 3 additions & 3 deletions src/main/resources/templates/console.ftl
Expand Up @@ -12,11 +12,11 @@
var websocket = new WebSocket(wsurl("console"));
websocket.onerror = function (evt)
{
alert("The websocket errored. Refresh the page!")
addAlert("The websocket errored. Refresh the page!")
};
websocket.onclose = function (evt)
{
alert("The websocket closed. Refresh the page!")
addAlert("The websocket closed. Refresh the page!")
};
function htmlDecode(input)
Expand All @@ -31,7 +31,7 @@
var temp = JSON.parse(evt.data);
if (temp.status !== "ok")
{
alert(temp.message);
addAlert(temp.message);
}
else
{
Expand Down
8 changes: 4 additions & 4 deletions src/main/resources/templates/editors/ace.ftl
Expand Up @@ -21,7 +21,7 @@
var modes = ["abap", "actionscript", "ada", "apache_conf", "applescript", "asciidoc", "assembly_x86", "autohotkey", "batchfile", "c9search", "cirru", "clojure", "cobol", "coffee", "coldfusion", "csharp", "css", "curly", "c_cpp", "d", "dart", "diff", "django", "dockerfile", "dot", "eiffel", "ejs", "erlang", "forth", "ftl", "gcode", "gherkin", "gitignore", "glsl", "golang", "groovy", "haml", "handlebars", "haskell", "haxe", "html", "html_ruby", "ini", "io", "jack", "jade", "java", "javascript", "json", "jsoniq", "jsp", "jsx", "julia", "latex", "less", "liquid", "lisp", "livescript", "logiql", "lsl", "lua", "luapage", "lucene", "makefile", "markdown", "matlab", "mel", "mushcode", "mysql", "nix", "objectivec", "ocaml", "pascal", "perl", "pgsql", "php", "plain_text", "powershell", "praat", "prolog", "properties", "protobuf", "python", "r", "rdoc", "rhtml", "ruby", "rust", "sass", "scad", "scala", "scheme", "scss", "sh", "sjs", "smarty", "snippets", "soy_template", "space", "sql", "stylus", "svg", "tcl", "tex", "text", "textile", "toml", "twig", "typescript", "vala", "vbscript", "velocity", "verilog", "vhdl", "xml", "xquery", "yaml"];
var modeSelector = document.getElementById("modeSelector");
var modeSelector = get("modeSelector");
modes.forEach(function (mode)
{
modeSelector.innerHTML += "<option value=\"" + mode + "\">" + mode + "</option>";
Expand Down Expand Up @@ -52,11 +52,11 @@
var websocket = new WebSocket(wsurl("filemanager/${server.ID?js_string}/${fm.stripServer(fm.getFile())?js_string}"));
websocket.onerror = function (evt)
{
alert("The websocket errored. Refresh the page!")
addAlert("The websocket errored. Refresh the page!")
};
websocket.onclose = function (evt)
{
alert("The websocket closed. Refresh the page!")
addAlert("The websocket closed. Refresh the page!")
};
websocket.onmessage = function (evt)
{
Expand All @@ -68,7 +68,7 @@
}
else
{
alert(temp.message);
addAlert(temp.message);
}
};
function send(data)
Expand Down

0 comments on commit 1094418

Please sign in to comment.