Drools not firing - strange refactoring
blabno Jul 11, 2009 2:30 AMI have rule :
rule ModifyPrivateFacility no-loop when $perm: PermissionCheck(name=="facilityHome", action in ("update", "remove"), granted == false) //Role(name == "admin") //Facility(type == "PRIVATE") $f: Facility() // or match multiple types -> Facility(type == "PRIVATE" || == "RESORT") then System.out.println($f); $perm.grant(); end
So there should be no way this rule could fail (according to Dan's book) on #{s:hasPermission('facilityHome','update',facilityHome.instance)}.
However the rule fails (seam 2.1.1.GA). After long hours I've inspected seam's source code and found out that Dan's version of seam (2.0.3.CR1) has RuleBasedIdentity.java which has different implementation of Identity.hasPermission(String,String,Object...) :
@Override public boolean hasPermission(String name, String action, Object...arg) { if (!securityEnabled) return true; StatefulSession securityContext = getSecurityContext(); if (securityContext == null) return false; List<FactHandle> handles = new ArrayList<FactHandle>(); PermissionCheck check = new PermissionCheck(name, action); synchronized( securityContext ) { synchronizeContext(); handles.add( securityContext.insert(check) ); for (int i = 0; i < arg.length; i++) { if (i == 0 && arg[0] instanceof Collection) { for (Object value : (Collection) arg[i]) { if ( securityContext.getFactHandle(value) == null ) { handles.add( securityContext.insert(value) ); } } } else { handles.add( securityContext.insert(arg[i]) ); } } securityContext.fireAllRules(); for (FactHandle handle : handles) securityContext.retract(handle); } return check.isGranted(); }
This makes sens for me. But check out seam 2.1.1.GA - it does not have RuleBasedIdentity class; instead it has hasPermission method in Identity class :
public boolean hasPermission(String name, String action, Object...arg) { if (!securityEnabled) return true; if (systemOp != null && Boolean.TRUE.equals(systemOp.get())) return true; if (permissionMapper == null) return false; if (arg != null) { return permissionMapper.resolvePermission(arg[0], action); } else { return permissionMapper.resolvePermission(name, action); } }
Please note this :
if (arg != null) { return permissionMapper.resolvePermission(arg[0], action); }
From now on rules that have this : name attribute in PermissionCheck i.e. : PermissionCheck(name==facilityHome
)
will not fire !
I consider this a serious bug. If I'm wrong please explain it to me.