Skip to content

Commit

Permalink
Various cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
tresf committed Apr 24, 2024
1 parent 76335e0 commit 53d38a0
Show file tree
Hide file tree
Showing 8 changed files with 263 additions and 269 deletions.
20 changes: 0 additions & 20 deletions src/qz/ws/substitutions/RestrictedKey.java

This file was deleted.

63 changes: 0 additions & 63 deletions src/qz/ws/substitutions/RootKey.java

This file was deleted.

9 changes: 9 additions & 0 deletions src/qz/ws/substitutions/SubstitutionException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package qz.ws.substitutions;

import org.codehaus.jettison.json.JSONException;

public class SubstitutionException extends JSONException {
public SubstitutionException(String message) {
super(message);
}
}
120 changes: 76 additions & 44 deletions src/qz/ws/substitutions/Substitutions.java
Original file line number Diff line number Diff line change
@@ -1,31 +1,41 @@
package qz.ws.substitutions;

import org.apache.commons.io.IOUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class Substitutions {
protected static final Logger log = LogManager.getLogger(Substitutions.class);

// Subkeys that are restricted for writing
private static boolean restrictSubstitutions = true;
private ArrayList<JSONObject> matches;
private ArrayList<JSONObject> replaces;
private static HashMap<String, Type> restricted = new HashMap<>();
static {
restricted.put("copies", Type.OPTIONS);
restricted.put("data", Type.DATA);
}
private ArrayList<JSONObject> matches, replaces;

private static class SubstitutionException extends JSONException {
public SubstitutionException(String message) {
super(message);
}
public Substitutions(InputStream in) throws IOException, JSONException {
this(IOUtils.toString(in, StandardCharsets.UTF_8));
}

public Substitutions(String serialized) throws JSONException {
matches = new ArrayList<>();
replaces = new ArrayList<>();

JSONArray instructions = new JSONArray(serialized);
System.out.println(serialized);
for(int i = 0; i < instructions.length(); i++) {
JSONObject step = instructions.optJSONObject(i);
if(step != null) {
Expand All @@ -47,15 +57,20 @@ public Substitutions(String serialized) throws JSONException {
}
}

public void replace(JSONObject base) throws JSONException {
public JSONObject replace(InputStream in) throws IOException, JSONException {
return replace(new JSONObject(IOUtils.toString(in, StandardCharsets.UTF_8)));
}

public JSONObject replace(JSONObject base) throws JSONException {
for(int i = 0; i < matches.size(); i++) {
if (find(base, matches.get(i))) {
System.out.println(" [YES MATCH]");
log.debug("Matched JSON substitution rule: for: {}, use: {}", matches.get(i), replaces.get(i));
replace(base, replaces.get(i));
} else {
System.out.println(" [NO MATCH]");
log.debug("Unable to match substitution rule: for: {}, use: {}", matches.get(i), replaces.get(i));
}
}
return base;
}

public static boolean isPrimitive(Object o) {
Expand All @@ -66,63 +81,78 @@ public static boolean isPrimitive(Object o) {
}

public static void replace(JSONObject base, JSONObject replace) throws JSONException {
JSONObject baseParams = base.optJSONObject("params");
JSONObject replaceParams = replace.optJSONObject("params");
if(baseParams == null) {
JSONObject jsonBase = base.optJSONObject("params");
JSONObject jsonReplace = replace.optJSONObject("params");
if(jsonBase == null) {
// skip, invalid base format for replacement
return;
}
if(replaceParams == null) {
if(jsonReplace == null) {
throw new SubstitutionException("Replacement JSON is missing \"params\": and is malformed");
}

// Second pass of sanitization before we replace
for(Iterator it = replaceParams.keys(); it.hasNext();) {
RootKey root = RootKey.parse(it.next());
if(root != null && root.isReplaceAllowed()) {
for(Iterator it = jsonReplace.keys(); it.hasNext();) {
Type type = Type.parse(it.next());
if(type != null && !type.isReadOnly()) {
// Good, let's make sure there are no exceptions
if(restrictSubstitutions) {
switch(root) {
switch(type) {
// Special handling for arrays
case DATA:
JSONArray data = (JSONArray)replaceParams.get(root.getKey());
ArrayList<Object> toRemove = new ArrayList();
for(int i = 0; i < data.length(); i++) {
JSONObject jsonObject;
if ((jsonObject = data.optJSONObject(i)) != null) {
for(RestrictedKey restricted : root.getRestrictedSubkeys()) {
if (jsonObject.has(restricted.getSubkey())) {
log.warn("Use of {}: [{}:] is restricted, removing", root.getKey(), restricted.getSubkey());
toRemove.add(jsonObject);
}
}
}
}
for(Object o : toRemove) {
data.remove(o);
}
JSONArray jsonArray = jsonReplace.optJSONArray(type.getKey());
removeRestrictedSubkeys(jsonArray, type);
break;
default:
for(RestrictedKey restricted : root.getRestrictedSubkeys()) {
if (replaceParams.has(restricted.getSubkey())) {
log.warn("Use of {}: [{}:] is restricted, removing", root.getKey(), restricted.getSubkey());
replaceParams.remove(restricted.getSubkey());
}
}
removeRestrictedSubkeys(jsonReplace, type);
}
}
}
}
find(base, replace, true);
}

private static void removeRestrictedSubkeys(JSONObject jsonObject, Type type) {
if(jsonObject == null) {
return;
}
for(Map.Entry<String, Type> entry : restricted.entrySet()) {
if (type == entry.getValue()) {
JSONObject toCheck = jsonObject.optJSONObject(type.getKey());
if(toCheck != null && toCheck.has(entry.getKey())) {
log.warn("Use of { \"{}\": { \"{}\": ... } } is restricted, removing", type.getKey(), entry.getKey());
jsonObject.remove(entry.getKey());
}
}
}
}
private static void removeRestrictedSubkeys(JSONArray jsonArray, Type type) {
if(jsonArray == null) {
return;
}
ArrayList<Object> toRemove = new ArrayList();
for(int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject;
if ((jsonObject = jsonArray.optJSONObject(i)) != null) {
for(Map.Entry<String, Type> entry : restricted.entrySet()) {
if (jsonObject.has(entry.getKey()) && type == entry.getValue()) {
log.warn("Use of { \"{}\": { \"{}\": ... } } is restricted, removing", type.getKey(), entry.getKey());
toRemove.add(jsonObject);
}
}
}
}
for(Object o : toRemove) {
jsonArray.remove(o);
}
}

public static void sanitize(JSONObject match) throws JSONException {
// "options" ~= "config"
System.out.println("BEFORE: " + match);
Object cache;


for(RootKey key : RootKey.values()) {
for(Type key : Type.values()) {
// Sanitize alts/aliases
for(String alt : key.getAlts()) {
if ((cache = match.optJSONObject(alt)) != null) {
Expand Down Expand Up @@ -165,8 +195,6 @@ public static void sanitize(JSONObject match) throws JSONException {
}
}
}

System.out.println("AFTER: " + match);
}

private static boolean find(Object base, Object match) throws JSONException {
Expand Down Expand Up @@ -226,4 +254,8 @@ private static boolean find(Object base, Object match, boolean replace) throws J
return match.equals(base);
}
}

public static void setRestrictSubstitutions(boolean restrictSubstitutions) {
Substitutions.restrictSubstitutions = restrictSubstitutions;
}
}
41 changes: 41 additions & 0 deletions src/qz/ws/substitutions/Type.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package qz.ws.substitutions;

public enum Type {
OPTIONS("options", "config"),
PRINTER("printer"),
DATA("data");

private String key;
private boolean readOnly;
private String[] alts;

Type(String key, String ... alts) {
this(key, false, alts);
}
Type(String key, boolean readOnly, String... alts) {
this.key = key;
this.readOnly = readOnly;
this.alts = alts;
}

public boolean isReadOnly() {
return readOnly;
}

public static Type parse(Object o) {
for(Type root : values()) {
if (root.key.equals(o)) {
return root;
}
}
return null;
}

public String getKey() {
return key;
}

public String[] getAlts() {
return alts;
}
}
Loading

0 comments on commit 53d38a0

Please sign in to comment.