use of org.casbin.jcasbin.effect.Effect in project jcasbin by casbin.
the class CoreEnforcer method enforce.
/**
* enforce use a custom matcher to decide whether a "subject" can access a "object" with the operation "action",
* input parameters are usually: (matcher, sub, obj, act), use model matcher by default when matcher is "" or null.
*
* @param matcher the custom matcher.
* @param rvals the request needs to be mediated, usually an array
* of strings, can be class instances if ABAC is used.
* @return whether to allow the request.
*/
private boolean enforce(String matcher, Object... rvals) {
if (!enabled) {
return true;
}
boolean compileCached = true;
if (fm.isModify) {
compileCached = false;
initBuiltInFunction();
fm.isModify = false;
}
Map<String, AviatorFunction> gFunctions = new HashMap<>();
if (model.model.containsKey("g")) {
for (Map.Entry<String, Assertion> entry : model.model.get("g").entrySet()) {
String key = entry.getKey();
Assertion ast = entry.getValue();
RoleManager rm = ast.rm;
AviatorFunction aviatorFunction = BuiltInFunctions.GenerateGFunctionClass.generateGFunction(key, rm);
gFunctions.put(key, aviatorFunction);
}
}
for (AviatorFunction f : gFunctions.values()) {
if (!aviatorEval.containsFunction(f.getName())) {
aviatorEval.addFunction(f);
compileCached = false;
}
}
fm.setAviatorEval(aviatorEval);
String rType = "r", pType = "p", eType = "e", mType = "m";
if (rvals.length != 0) {
if (rvals[0] instanceof EnforceContext) {
EnforceContext enforceContext = (EnforceContext) rvals[0];
rType = enforceContext.getrType();
pType = enforceContext.getpType();
eType = enforceContext.geteType();
mType = enforceContext.getmType();
rvals = Arrays.copyOfRange(rvals, 1, rvals.length);
}
}
String expString;
if (matcher == null || "".equals(matcher)) {
expString = model.model.get("m").get(mType).value;
} else {
expString = Util.removeComments(Util.escapeAssertion(matcher));
}
expString = Util.convertInSyntax(expString);
// Use md5 encryption as cacheKey to prevent expString from being too long
Expression expression = aviatorEval.compile(Util.md5(expString), expString, compileCached);
StreamEffector streamEffector = null;
try {
streamEffector = this.eft.newStreamEffector(model.model.get("e").get(eType).value);
} catch (Exception e) {
if (!(e instanceof UnsupportedOperationException)) {
throw new CasbinEffectorException(e);
}
}
Effect[] policyEffects;
float[] matcherResults;
int policyLen;
if ((policyLen = model.model.get("p").get(pType).policy.size()) != 0) {
policyEffects = new Effect[policyLen];
matcherResults = new float[policyLen];
for (int i = 0; i < model.model.get("p").get(pType).policy.size(); i++) {
List<String> pvals = model.model.get("p").get(pType).policy.get(i);
// Util.logPrint("Policy Rule: " + pvals);
// Select the rule based on request size
Map<String, Object> parameters = new HashMap<>();
getRTokens(parameters, rvals);
for (int j = 0; j < model.model.get("p").get(pType).tokens.length; j++) {
String token = model.model.get("p").get(pType).tokens[j];
parameters.put(token, pvals.get(j));
}
Object result = expression.execute(parameters);
if (result instanceof Boolean) {
if (!((boolean) result)) {
policyEffects[i] = Effect.Indeterminate;
} else {
policyEffects[i] = Effect.Allow;
}
if (streamEffector == null) {
continue;
}
} else if (result instanceof Float) {
if ((float) result == 0) {
policyEffects[i] = Effect.Indeterminate;
} else {
matcherResults[i] = (float) result;
policyEffects[i] = Effect.Allow;
}
if (streamEffector == null) {
continue;
}
} else {
throw new CasbinMatcherException("matcher result should be bool, int or float");
}
if (policyEffects[i] == Effect.Allow && parameters.containsKey(pType + "_eft")) {
String eft = (String) parameters.get(pType + "_eft");
if ("allow".equals(eft)) {
policyEffects[i] = Effect.Allow;
} else if ("deny".equals(eft)) {
policyEffects[i] = Effect.Deny;
} else {
policyEffects[i] = Effect.Indeterminate;
}
}
if (streamEffector != null) {
boolean done = streamEffector.push(policyEffects[i], i, policyLen);
if (done) {
break;
}
} else {
if ("priority(p_eft) || deny".equals(model.model.get("e").get(eType).value)) {
break;
}
}
}
} else {
policyEffects = new Effect[1];
matcherResults = new float[1];
Map<String, Object> parameters = new HashMap<>();
for (int j = 0; j < model.model.get("r").get(rType).tokens.length; j++) {
String token = model.model.get("r").get(rType).tokens[j];
parameters.put(token, rvals[j]);
}
for (int j = 0; j < model.model.get("p").get(pType).tokens.length; j++) {
String token = model.model.get("p").get(pType).tokens[j];
parameters.put(token, "");
}
Object result = expression.execute(parameters);
if (streamEffector != null) {
if ((boolean) result) {
streamEffector.push(Effect.Allow, 0, 1);
} else {
streamEffector.push(Effect.Indeterminate, 0, 1);
}
} else {
if ((boolean) result) {
policyEffects[0] = Effect.Allow;
} else {
policyEffects[0] = Effect.Indeterminate;
}
}
}
boolean result;
if (streamEffector != null && streamEffector.current() != null) {
result = streamEffector.current().hasEffect();
} else {
result = eft.mergeEffects(model.model.get("e").get(eType).value, policyEffects, matcherResults);
}
StringBuilder reqStr = new StringBuilder("Request: ");
for (int i = 0; i < rvals.length; i++) {
String rval = rvals[i].toString();
if (i != rvals.length - 1) {
reqStr.append(String.format("%s, ", rval));
} else {
reqStr.append(String.format("%s", rval));
}
}
reqStr.append(String.format(" ---> %s", result));
Util.logPrint(reqStr.toString());
return result;
}
Aggregations