3 Replies Latest reply on Feb 11, 2010 11:00 PM by David Hibbs

    Rule syntax in security.drl, SEAM 2.2.0_EAP5 (w JBDevS)

    David Hibbs Newbie

      I'm still relatively new to Seam, and have been working on learning how to write rules in the security.drl file to protect certain operations.


      I've looked at the basic examples, and I can get the most basic cases to work.  i.e. verify the user is logged in and is in the proper role.


      My problem comes in when I try to write a more sophisticated check.  It seems like everything I try with respect to inspecting object attributes causes the rule compilation to fail with a cryptic error:


      Caused by: org.jboss.seam.InstantiationException: Could not instantiate Seam component: securityRules
              at org.jboss.seam.Component.newInstance(Component.java:2144)
      ...
      Caused by: java.lang.NullPointerException
              at org.drools.common.AbstractRuleBase.addPackages(AbstractRuleBase.java:434)
              at org.drools.reteoo.ReteooRuleBase.addPackage(ReteooRuleBase.java:388)
              at org.jboss.seam.drools.RuleBase.compileRuleBase(RuleBase.java:115)
      ...



      Here's my scenario:  I have a number of internal roles which I do not want to allow users to delete.  So, on my role home, I have overridden the remove method to add a restrict tag:



      @Override
      @Restrict("#{s:hasPermission(imRoleHome.instance, 'remove')}")
      public String remove() 
      {
      return super.remove();
      }
      



      My rule is as follows:


      rule CanDeleteExtraRoles  
      dialect "mvel"
      no-loop true
      when  
      exists Principal()
      $testRole : MyRole( )
      $check: PermissionCheck(target == $testRole, action == "remove", granted == false)  
      Role(name == "my_admin")  
      then  
      $check.grant();  
      end
      



      So far, so good.  When I deploy the application, everything operates as expected.  The user must be in the proper admin role in order to delete a role at all.


      Now, I want to enhance this rule further so that roles with a certain prefix can never be deleted, i.e.


      my_role1, my_role2, my_role3
      



      How do I check the roleName attribute on my role class?  I know mvel allows regexp, but even before I get to that point I try some simple checks.  For example, I add the line


      $testRole.roleName != "my_admin" 
      



      above the role check, and it won't compile the rules.  What is the right process to define local variables and then do comparisons/checks against them, or against fields on those objects?


      Is there an example app that I just haven't found yet? Any help is appreciated.

        • 1. Re: Rule syntax in security.drl, SEAM 2.2.0_EAP5 (w JBDevS)
          bb bb Master
          eval(! $testRole.roleName.equals("my_admin"))
          • 2. Re: Rule syntax in security.drl, SEAM 2.2.0_EAP5 (w JBDevS)
            David Hibbs Newbie

            Thanks!  That gets me closer.  From there, I ended up with


            11:56:46,391 ERROR [RuleBase] Unable to build expression for 'eval':Failed to compile: 2 compilation error(s): 
             - (1,9) unqualified type in strict mode for: $testRole
             - (1,18) unqualified type in strict mode for: roleName '! $testRole.roleName.equals("my_admin")' (/META-INF/security.drl)
            



            Which was easy enough for me to search up.  I simply added


            -Ddrools.dialect.mvel.strict=false 
            



            to my server configuration.  Then I ran into a new compile issue...


             Caused by: org.drools.rule.InvalidRulePackage: Unable to determine the used declarations.
            negation operator cannot be applied to non-boolean type : [Rule name='CanDeleteExtraRoles']
            Unable to build expression for 'eval':negation operator cannot be applied to non-boolean type ' !$testRole.roleName.equals("my_admin") ' : [Rule name='CanDeleteExtraRoles']
            [Error: negation operator cannot be applied to non-boolean type]
            [Near : {... leName.equals("my_admin" ....}]
            



            So I took out the negation (!) and it compiles and works... but of course is the opposite of what I want.


            I've tried moving the negation out front ( !eval( ... ), using extra parens, and even using 'not' instead of the exclamation point.  These all take me back to the original exception.


            Any further advice?

            • 3. Re: Rule syntax in security.drl, SEAM 2.2.0_EAP5 (w JBDevS)
              David Hibbs Newbie

              aha!  Figured out the proper way to use the not syntax:


              not(
                   eval( $testRole.roleName.startsWith("my_") )
              )
              



              Thanks again for the help... it got me pointed in the right direction.