3 Replies Latest reply on Oct 14, 2009 9:55 PM by Matthias Age

    Drools not firing - strange refactoring

    Bernard Labno Master

      I 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.