views:

463

answers:

1

Hello,

I would like to intercept calls to properties of domain classes to implement access control.

My first try was to override setProperty and getProperty. By doing this, I disabled all nice functionality of Grails domain classes, such as

domainClass.properties = params

and the automatic conversion of data types.

The next try was to use the DelegatingMetaClass, which enabled me at least to print out some nice log messages around the actual call. But I could not figure out how to access the actual object to evaluate the permissions.

Last, groovy.lang.Interceptor seems to be a good choice, as I can access the actual object. But is this the right way? How am I able to force all domain classes to be intercepted?

Thanks a lot in advance.

Regards, Daniel

+3  A: 

You can override getProperty and setProperty as long as you reference the real versions. Add code like this to BootStrap for add interceptors for all domain classes:

class BootStrap {

   def grailsApplication

   def init = { servletContext ->

      for (dc in grailsApplication.domainClasses) {
         dc.class.metaClass.getProperty = { String name ->
            // do stuff before access
            def result
            def metaProperty = delegate.class.metaClass.getMetaProperty(name)
            if (metaProperty) {
               result = metaProperty.getProperty(delegate)
            }
            else {
               throw new MissingPropertyException(name, delegate.class)
            }
            // do stuff after access
            result
         }

         dc.class.metaClass.setProperty = { String name, value ->
            // do stuff before update
            def metaProperty = delegate.class.metaClass.getMetaProperty(name)
            if (metaProperty) {
               metaProperty.setProperty(delegate, value)
            }
            else {
               throw new MissingPropertyException(name, delegate.class)
            }
            // do stuff after update
         }
      }
   }

   def destroy = {}
}
Burt Beckwith
Hello,Thanks a lot for your fast reply.Your code does help me a lot. Unfortunately I can not see, how to call a method on my domain class object. For instance, I have a domain class called A, which provides a method called isReadable(String propertyName). So how can I call this function within the get or setProperty-method? I can find the meta method via delegate.metaClass.getMetaMethod("isReadable", java.lang.String), but invoking always leads to an exception (java.lang.IllegalArgumentException: object is not an instance of declaring class).Regards, Daniel
Daniel
Burt Beckwith
Thanks for your reply. But I don't understand, why I cannnot access methods within the class. I thought, that by defining the setProperty method, this method is actually replaced as if it was written in the domain class itself. Your PropertyChecker example suggests, that I cannot work with an actual object but rather with a class. Unfortunately this is not sufficient for me as the object itself calculates the rights depending on its state. Are there any other possibilites how to intercept the set and get property calls? Regards, Daniel
Daniel