3 Replies Latest reply on Jan 30, 2009 3:07 PM by Sylvain Catudal

    hasPermission

    Marc Alringer Newbie

      I'm using Seam 2.0.1.GA on Jboss 4.2.0.GA. We have an existing ap using role-based security but want to add permissions. As a test, I extended Identity.hasPermissions and referenced it from a seam page using


      <h:outputText value="Edit" rendered="#{identity.loggedIn and (s:hasPermission('Edit Account', 'edit', null))}"/>



      I added a log statement to the hasPermission method and was surprised to see it called 5 times every time I hit the page! I thought it might be drools (4.0.7) so I took drools out of the equation. Components.xml now has ...


         <security:identity authenticate-method="#{authenticator.authenticate}"/>



      where previously it referenced security.drl. hasPermission still gets called 5 times! Anyone know what's going on here?


      Here's my hasPermission override method ...


      @Name("org.jboss.seam.security.identity")
      @Scope(ScopeType.SESSION) @Startup
      @Install(precedence = Install.APPLICATION)
      public class HedgeIdentity extends Identity 
      {
          @Logger Log log;
          
           private Map<String, String> permissions;
           private String roleType = "Member";
           private Integer id = null;
           
           public boolean hasPermission(String name, String action, Object...arg)
           {      
                log.info("has: Name=#0, Action=#1", name, action);
           //     String value = permissions == null ? null : permissions.get(name);
           //     return value == null ? false : value.equals(action);
                return true;
           }   
      ... 








        • 1. Re: hasPermission
          Marc Alringer Newbie

          Just out of curiousity, I overrode hasRole() and got the same behavior. I have no idea why it is being called more than once.

          • 2. Re: hasPermission
            Sylvain Catudal Newbie

            I didn't overide anything and I have exactly the same behavior.


            Here is the two rules I used to test this:



            package Permissions;
            
            import org.jboss.seam.security.permission.PermissionCheck;
            import org.jboss.seam.security.Role;
            
            rule GenericHasRole
              no-loop
            when
              $perm: PermissionCheck($target: target, granted == false)
              Role(name == $target)
            then
              $perm.grant();
            end
            
            rule Logger
              no-loop
            when
              $perm: PermissionCheck($action: action, $target: target)
            then
              System.out.println(  $target + "." + $action 
                        + " : $perm.granted = " + $perm.isGranted());
            end



            Here is the s:link in which I test it.



            <s:link view="/test.xhtml" value="Manage Roles"
                 includePageParams="false"
                 rendered="#{s:hasPermission('roleManager','showlink')}"
                 propagation="none" />



            And here is the trace in my console...



            15:07:46,645 INFO  [STDOUT] roleManager.showlink : $perm.granted = true
            15:07:46,645 INFO  [STDOUT] roleManager.showlink : $perm.granted = true
            15:07:46,645 INFO  [STDOUT] roleManager.showlink : $perm.granted = true
            15:07:46,645 INFO  [STDOUT] roleManager.showlink : $perm.granted = true
            15:07:46,645 INFO  [STDOUT] roleManager.showlink : $perm.granted = true
            15:07:46,645 INFO  [STDOUT] roleManager.showlink : $perm.granted = true



            I'm working with jboss-seam-2.1.1.GA and jboss-5.0.0.GA


            Did you figure out what caused the system to act this way?

            • 3. Re: hasPermission
              Sylvain Catudal Newbie

              I looked a bit more into it and here is what I found.  I created a very simple backing bean for a test page that had nothing else in it then a s:link.  Here is the code for the backing bean:


              package ca.mcgill.muhc.scn.action;
              
              import org.jboss.seam.annotations.Name;
              import org.jboss.seam.annotations.Logger;
              import org.jboss.seam.log.Log;
              
              @Name("alwaysTrue")
              public class AlwaysTrueBean 
              {
                  @Logger Log log;
              
                  boolean alwaysTrue = true;
                  int count = 0;
                  
                   public boolean isAlwaysTrue() {
                        count++;
                      log.info("alwaysTrue has been called (count = {0})", count);
                        return alwaysTrue;
                   }
              
                   public void setAlwaysTrue(boolean alwaysTrue) {
                        this.alwaysTrue = alwaysTrue;
                   }
              
              }
              



              Here is the s:link in question that I included in an empty page:



              <s:link view="/home.xhtml" value="Home" rendered="#{alwaysTrue.alwaysTrue}" />



              Here is the trace:



              08:58:56,822 INFO  [AlwaysTrueBean] alwaysTrue has been called (count = 1)
              08:58:56,822 INFO  [AlwaysTrueBean] alwaysTrue has been called (count = 2)
              08:58:56,822 INFO  [AlwaysTrueBean] alwaysTrue has been called (count = 3)
              08:58:56,822 INFO  [AlwaysTrueBean] alwaysTrue has been called (count = 4)
              08:58:56,822 INFO  [AlwaysTrueBean] alwaysTrue has been called (count = 5)



              Can't have a simpler test then that.  The rendered attribute is evaluated at least 5 times.


              It's discussed in this JIRA:
              JBSEAM-3008


              In conclusion, since it will likely stay this way for quite some time, you have to make sure that the expression evaluated in the rendered attribute is very lightweight or that you cache the result in your backing bean after it's been evaluated.


              Sylvain