views:

259

answers:

2

Hi

I am developing a grails application.In that some cases I want to control the domain class fields based on the role.So that in each call to getter setter method of domain class I want to apply some filter based on role(Logged in user's role).I am assuming that grails will create getter setter method at runtime for the domin classes.So while writing grails code is it possible to apply this logic.If it is possible then how to apply?

Example:

Domain Class :

class Book{
   String name;
   double price;

  }

Controller:

def index={
  Book book=Book.get(1);
   println book.name;
   println book.price;
 }

In the above code "println book.price;" this line should work only for particular role.For some other role it should throw some exception.

Is it possible achieve?Is there any plugin to do this?

Please give some help on this....Thanks

A: 

You can create get/set methods for the properties you want to control access to and put your security logic there. Assuming you've written your own security service or are using a security plugin like the Spring Security (Acegi) plugin you would:

class Book{
    String name;
    double price;

    def authenticateService

    void setPrice(double price) {
        if(!authenticateService.ifAllGranted('ROLE_PRICE_FIXER')) {
            throw new Exception("You are not authorized to set book prices")
        }
        this.price = price
    }

    double getPrice() {
        if(!authenticateService.ifAllGranted('ROLE_PRICE_FIXER')) {
            throw new Exception("You are not authorized to get book prices")
        }
        return this.price
    }
}

I am not aware of any plugin that allows access controls to be put on domain properties.

John Wagenleitner
A: 

You could also consider using a custom validator or a spring errors object to catch attempts to set a field before saving it.

EDIT: Here is an example of what I was thinking. You could generalize quite a bit more and the code here hasn't been tested so it probably won't run as is.

class securedDomain {
    String securedField

    def fieldSetBy = [:]
    def previousValue = [:]
    static transients = ['fieldSetBy', 'previousValue']

    static constraints = {
        securedField(validator: { v, o ->
             def access = User.findByName(fieldSetBy['securedField']).hasAccess('securedField')
             if(!access) securedField = previousValue['securedField']
             return access
        })

    void setProperty(String name, value) {
        if(name == "securedField") {
            fieldSetBy['securedField'] = session.user
            previousValue['securedField'] = securedField
            securedField = value
        } else {
            super(name, value)
        }
    }
Blacktiger
Can you please provide some sample code.
BlackPanther
Sure, I edited the post to give a sample of what I was thinking.
Blacktiger