4 Replies Latest reply on Jun 19, 2008 5:40 AM by btonez

    Expiring Permissions

    btonez

      I'm wondering if Seam's new security model would permit permissions that expire.  So, for instance, I need a User to be able to edit a Document only until a Date.  If the User tries to edit it after Date, the permission would be removed from the JPA store.  Other permissions for the target would be unaltered, or independently expire.  I would rather not roll my own permissions checking infrastructure.


      I know that you can use event listeners to access the raw user account class when the IdentityManager creates a user.  Would a similar approach be used here to access the raw account permissions class, where the date is stored in an unannotated field?


      Thanks,
      Brenton

        • 1. Re: Expiring Permissions

          If you are not tied to having to store/remove the permission, an option would be to use rule-based permissioning on instance values which is directly supported.  Something like the following:


          rule EditDocumentPermission
          when
            c: PermissionCheck(name == "documentAction", action == "edit")
            DocumentAction($currentDate : currentDate)
            Document(permittedUser == currentUser, 
              endEditingDate > $currentDate)
          then
            c.grant();
          end;



          This of course does not remove the permission from the JPA store, but instead bases permissions on instance variables.

          • 2. Re: Expiring Permissions
            btonez

            Thanks for the excellent example!  Unfortunately, as I must support multiple arbitrary users and roles  per document, each with different privileges, a persistent permissions table is crucial.  Any other ideas?

            • 3. Re: Expiring Permissions

              Perhaps you could still use rules-based permissioning, but perform a programmatic permission check.  If the permission check fails remove the role:


              @In Identity identity;
              
              public void editDocument() {
                if(identity.hasPermission("documentAction", "edit", user, document)) {
                  // allow editing
                } else {
                  // perform remove operation
              
                  throw new AuthorizationException("User is not authorized");
                }
              }
              



              If you want to integrate this logic with Seam here, you could override the Identity.hasPermission() method to perform the removal logic when the permission check fails in a restriction.  This would likely be a bit cleaner than the above but does require overriding a Seam component.


              Hope it helps.

              • 4. Re: Expiring Permissions
                btonez

                Thanks so much.  I decided to roll my own solution, not using Seam security but still looking very Seam-like, using Seam interception.  Although I haven't tested it yet, it should work in theory. 


                Basically, I'm making a custom entity that functions like a join table from User to Document, but also with the expiry date and an access type.  Then, I have a DocumentPrivileges component with check(Document, AccessType) method that queries the entity manager for the Access entities, checks if invalid, and removes/throws exception if necessary.  Then, I have an Interceptor or each AccessType that precedes the forwarded invocation with:


                DocumentPrivileges.instance().check(Component.getInstance(Document.class), "Write");
                



                Then, I have this:


                @Interceptors(WriteInterceptor.class)
                public @interface WriteDocument {}
                



                and then it's just @WriteDocument public void doIt() {...}.


                Again, no guarantees, just wanted to share my solution for the community.


                Brenton Partridge