7 Replies Latest reply on Nov 6, 2008 9:09 AM by shane.bryzak

    Using PermissionManager correctly

    nbhatia.bhatian.comcast.net

      I am trying to understand how to use PermissionManager correctly. I want to do a query which gets me all objects of a certain type on which the logged in user can perform a certain action. For example, get me all Accounts that I have view permission on. How do I do that? I would have thought that PermissionManager.listPermissions() method would do something like that, but I don't think that is the intended usecase.


      Is the PermissionSearch class supposed to do something like this (there is no javadoc on this class).


      Thanks.
      Naresh

        • 1. Re: Using PermissionManager correctly
          shane.bryzak

          Unfortunately you cannot execute database queries directly that take into account user permissions (that would be black magic indeed), however once you do have a query result you can filter the list of entities using Identity.filterByPermission(). 


          The PermissionSearch component is actually an action component used for creating a permission management view (see the seamspace example for its usage).

          • 2. Re: Using PermissionManager correctly
            nbhatia.bhatian.comcast.net

            Shane, I don't readily see how to do what you suggest. It seems that listPermissions(Object target) will list permissions for a single target, whereas I am trying to get permissions for a target type (for the specified recipient). I am not necessarily looking to execute database queries myself, but I think that the API ought to support something like this.


            The usecase I am trying to implement is fairly common for permissions management. My application manages thousands of accounts and I want to give different kinds of access to different users/groups. When a user goes to the account screen, they should be able to see only the accounts on which they have view permission. I don't see how I can use the query result from listPermissions() to do this.

            • 3. Re: Using PermissionManager correctly
              shane.bryzak

              Your code should look something like this:


              public List<Account> viewAccounts()
              {
                List<Account> accounts = entityManager.createQuery("select a from account a")
                  .getResultList();
              
                Identity.instance().filterByPermission(accounts, "view");
              
                return accounts;
              }



              What this method will do is return a list of Account objects for which the currently authenticated user has the view permission.

              • 4. Re: Using PermissionManager correctly
                nbhatia.bhatian.comcast.net

                Yep, I see how that would work. The only concern I have is that the unconditional query will pull in a million records from the database - this will certainly not scale very well.


                A side question - how does Identity.filterByPermission() figure out how to filter the provided collection of targets? Looking at the SeamSpace example, targets are identified in the AccountPermission table by strings in the format classname:id (e.g. MemberImage:5). How does Identity.filterByPermission() know where to split this string and match it to target objects? I tried to follow the code starting from filterByPermission() through resolvers etc. but could not figure out where this was happening.


                Thanks.
                Naresh

                • 5. Re: Using PermissionManager correctly
                  shane.bryzak

                  Unfortunately there's no easy way to filter the query itself by permissions.  I'm not saying it would be impossible, however there would be many many issues to overcome to actually do this.


                  As for how the actual objects are filtered out of the result list, take a look at PersistentPermissionResolver.filterSetByAction().  What it does is request a list of Permission objects for the set of targets from the PermissionStore, then iterates through each of the target objects to check if its permission exists in the list.  If not, it gets removed.

                  • 6. Re: Using PermissionManager correctly
                    nbhatia.bhatian.comcast.net

                    Getting closer :-). So my question is about line 129 in PersistentPermissionResolver.filterSetByAction():


                    if (permission.getTarget().equals(target))



                    How can this ever be true? As I understand it, permission.getTarget() will return a String like MemberImage:5 (see below) whereas target is an object of type MemberImage. These cannot be equal.


                    insert into AccountPermission (permissionId, recipient, target, action, discriminator)
                    values (1, 'friends', 'MemberImage:5', 'view', 'role');



                    I am sure I am missing something.


                    Naresh

                    • 7. Re: Using PermissionManager correctly
                      shane.bryzak

                      Target is the target object - don't be too concerned about the identifiers that are persisted in the database, these are just an implementation detail.