Search in sources :

Example 1 with Effect

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;
}
Also used : HashMap(java.util.HashMap) AviatorFunction(com.googlecode.aviator.runtime.type.AviatorFunction) DefaultRoleManager(org.casbin.jcasbin.rbac.DefaultRoleManager) RoleManager(org.casbin.jcasbin.rbac.RoleManager) Assertion(org.casbin.jcasbin.model.Assertion) CasbinEffectorException(org.casbin.jcasbin.exception.CasbinEffectorException) CasbinAdapterException(org.casbin.jcasbin.exception.CasbinAdapterException) CasbinMatcherException(org.casbin.jcasbin.exception.CasbinMatcherException) CasbinEffectorException(org.casbin.jcasbin.exception.CasbinEffectorException) CasbinMatcherException(org.casbin.jcasbin.exception.CasbinMatcherException) Expression(com.googlecode.aviator.Expression) StreamEffector(org.casbin.jcasbin.effect.StreamEffector) EnforceContext(org.casbin.jcasbin.util.EnforceContext) Effect(org.casbin.jcasbin.effect.Effect) HashMap(java.util.HashMap) Map(java.util.Map) FunctionMap(org.casbin.jcasbin.model.FunctionMap)

Aggregations

Expression (com.googlecode.aviator.Expression)1 AviatorFunction (com.googlecode.aviator.runtime.type.AviatorFunction)1 HashMap (java.util.HashMap)1 Map (java.util.Map)1 Effect (org.casbin.jcasbin.effect.Effect)1 StreamEffector (org.casbin.jcasbin.effect.StreamEffector)1 CasbinAdapterException (org.casbin.jcasbin.exception.CasbinAdapterException)1 CasbinEffectorException (org.casbin.jcasbin.exception.CasbinEffectorException)1 CasbinMatcherException (org.casbin.jcasbin.exception.CasbinMatcherException)1 Assertion (org.casbin.jcasbin.model.Assertion)1 FunctionMap (org.casbin.jcasbin.model.FunctionMap)1 DefaultRoleManager (org.casbin.jcasbin.rbac.DefaultRoleManager)1 RoleManager (org.casbin.jcasbin.rbac.RoleManager)1 EnforceContext (org.casbin.jcasbin.util.EnforceContext)1