diff --git a/engine/src/main/java/com/arcadedb/security/ACCM/Argument.java b/engine/src/main/java/com/arcadedb/security/ACCM/Argument.java index 6b624c096..4ea959450 100644 --- a/engine/src/main/java/com/arcadedb/security/ACCM/Argument.java +++ b/engine/src/main/java/com/arcadedb/security/ACCM/Argument.java @@ -104,38 +104,42 @@ private Object getValueForFieldJsonPath(JSONObject json) { } // TODO - remove seems like dead code. - public boolean isValid() { - - if (not) { - return !validate(); - } - return validate(); - } - - // TODO - remove seems like dead code. - private boolean validate() { - switch (operator) { - case EQ: - case NEQ: - case ANY_OF: - return value instanceof Object; - case GT: - case GT_EQ: - case LT: - case LT_EQ: - return value instanceof Integer; - case ANY_IN: - case ALL_IN: - case NONE_IN: - return value instanceof Object[]; - default: - return false; - } - } + // public boolean isValid() { + + // if (not) { + // return !validate(); + // } + // return validate(); + // } + + // // TODO - remove seems like dead code. + // private boolean validate() { + // switch (operator) { + // case EQ: + // case NEQ: + // case ANY_OF: + // return value instanceof Object; + // case CONTAINS: + + // case GT: + // case GT_EQ: + // case LT: + // case LT_EQ: + // return value instanceof Integer; + // case ANY_IN: + // case ALL_IN: + // case NONE_IN: + // return value instanceof Object[]; + // default: + // return false; + // } + // } public boolean evaluate(JSONObject json) { var result = evaluateInternal(json); + LogManager.instance().log(this, Level.INFO, "docValue: " + getValueForFieldJsonPath(json)); + if (getValueForFieldJsonPath(json) != null && isNot()) { result = !result; } @@ -155,6 +159,7 @@ private boolean evaluateInternal(JSONObject json) { // TODO configurably handle null values- could eval to true or false if (docFieldValue == null) { + LogManager.instance().log(this, Level.INFO, "Doc field value is null, returning null handling: " + this.nullEvaluatesToGrantAccess); return this.nullEvaluatesToGrantAccess; } @@ -199,28 +204,9 @@ private boolean evaluateInternal(JSONObject json) { return false; case CONTAINS: - if (docFieldValue instanceof JSONArray) { - for (Object docVal : ((JSONArray) docFieldValue).toList()) { - - String str = valueToString(); - str = str.substring(1, str.length() - 1).replace("\"", ""); - - // Split the string by commas - String[] stringArray = str.split(", "); - - LogManager.instance().log(this, Level.FINE, "Evaluation Values: " + Arrays.toString(stringArray)); - LogManager.instance().log(this, Level.FINE, "Doc Value: " + docVal); - - for (String val : stringArray) { - if (val.equals(docVal)) { - return true; - } - } - } - - return false; - } - return false; + return valueContains(docFieldValue); + case NOT_CONTAINS: + return !valueContains(docFieldValue); case GT: { if (this.value instanceof String) { return DocumentValidator.classificationOptions.get((String) docFieldValue) > DocumentValidator.classificationOptions.get((String) this.value); @@ -332,6 +318,36 @@ private boolean evaluateInternal(JSONObject json) { } } + private boolean valueContains(Object docFieldValue){ + + LogManager.instance().log(this, Level.INFO, "doc field value: " + docFieldValue.getClass().getSimpleName()); + + if (docFieldValue instanceof JSONArray) { + for (Object docVal : ((JSONArray) docFieldValue).toList()) { + + String str = valueToString(); + str = str.substring(1, str.length() - 1).replace("\"", ""); + + // Split the string by commas + String[] stringArray = str.split(","); + + LogManager.instance().log(this, Level.FINE, "Evaluation Values: " + Arrays.toString(stringArray)); + LogManager.instance().log(this, Level.FINE, "Doc Value: " + docVal); + + for (String val : stringArray) { + if (val.equals(docVal)) { + LogManager.instance().log(this, Level.INFO, "match found"); + return true; + } + } + } + LogManager.instance().log(this, Level.INFO, "broke out1"); + return false; + } + LogManager.instance().log(this, Level.INFO, "broke out2"); + return false; + } + @Override public String toString() { return "Argument [field=" + field + ", operator=" + operator + ", value=" + valueToString() + "]"; diff --git a/engine/src/main/java/com/arcadedb/security/ACCM/ArgumentOperator.java b/engine/src/main/java/com/arcadedb/security/ACCM/ArgumentOperator.java index 1aee94e85..28dcdb965 100644 --- a/engine/src/main/java/com/arcadedb/security/ACCM/ArgumentOperator.java +++ b/engine/src/main/java/com/arcadedb/security/ACCM/ArgumentOperator.java @@ -7,6 +7,7 @@ public enum ArgumentOperator { // Doc value contains the following option CONTAINS, + NOT_CONTAINS, // provided values contains diff --git a/server/src/main/java/com/arcadedb/server/security/oidc/OpaClient.java b/server/src/main/java/com/arcadedb/server/security/oidc/OpaClient.java index 9e58ed7cb..29658834e 100644 --- a/server/src/main/java/com/arcadedb/server/security/oidc/OpaClient.java +++ b/server/src/main/java/com/arcadedb/server/security/oidc/OpaClient.java @@ -119,14 +119,18 @@ public static OpaResponse getPolicy(String username, Set databaseNames) var readons = opaPolicyJson.get("programReadons").asText().replaceAll(" ","").split(","); Arrays.asList(readons); + List> allCombos = getAllCombinations(Arrays.asList(readons)); + allCombos.remove(0); // Remove first empty array option + // need an or expression to support any valid combo of program nicknames - for (List combo : getAllCombinations(Arrays.asList(readons))) { + for (List combo : allCombos) { Argument arg = new Argument("components.programNicknames", ArgumentOperator.ALL_IN, combo); arg.setNullEvaluatesToGrantAccess(true); accmArgs.add(arg); } } else { - var arg = new Argument("components.nonICmarkings", ArgumentOperator.CONTAINS, "ACCM", true); + var arg = new Argument("components.nonICmarkings", ArgumentOperator.NOT_CONTAINS, "ACCM"); + // arg.setNullEvaluatesToGrantAccess(false); accmArgs.add(arg); }