2010-02-11 6 views
2

Je voudrais intercepter des appels aux propriétés de classes de domaine pour implémenter le contrôle d'accès.Interception de propriété des classes de domaine Grails

Mon premier essai a consisté à remplacer setProperty et getProperty. En faisant cela, j'ai désactivé toutes les bonnes fonctionnalités des classes de domaine Grails, tels que

domainClass.properties = params 

et la conversion automatique des types de données. L'essai suivant consistait à utiliser la DelegatingMetaClass, ce qui m'a permis au moins d'imprimer quelques bons messages de journal autour de l'appel réel. Mais je ne pouvais pas comprendre comment accéder à l'objet réel pour évaluer les autorisations.

Enfin, groovy.lang.Interceptor semble être un bon choix, car je peux accéder à l'objet réel. Mais est-ce la bonne façon? Comment puis-je forcer l'interception de toutes les classes de domaine?

Merci beaucoup d'avance.

Cordialement, Daniel

Répondre

4

Vous pouvez remplacer getProperty et setProperty aussi longtemps que vous faites référence à des versions réelles. Ajouter un code comme celui-ci à Bootstrap pour intercepteurs add pour toutes les classes de domaine:

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 = {} 
} 
+0

Bonjour, Merci beaucoup pour votre réponse rapide. Votre code m'aide beaucoup. Malheureusement, je ne vois pas, comment appeler une méthode sur mon objet de classe de domaine. Par exemple, j'ai une classe de domaine appelée A, qui fournit une méthode appelée isReadable (String propertyName). Alors, comment puis-je appeler cette fonction dans la méthode get ou setProperty? Je peux trouver la méthode meta via delegate.metaClass.getMetaMethod ("isReadable", java.lang.String), mais invoquer mène toujours à une exception (java.lang.IllegalArgumentException: object n'est pas une instance de classe déclarante). Cordialement, Daniel – Daniel

+0

Une approche serait de remplacer le commentaire «faire les choses avant l'accès» par un appel à une classe d'aide et de faire la vérification d'accès là. Quelque chose comme "PropertyChecker.isReadable (delegate.class, name)" où PropertyChecker.isReadable (classe clazz, nom de chaîne) fait quelque chose comme "if (clazz == Person && name == 'username') {...}". Cet assistant peut également accéder à l'utilisateur connecté pour des contrôles d'accès plus précis. Cela deviendrait vite moche, donc vous aurez envie de trouver un moyen compact de représenter ce que les gens sont autorisés à changer ou à lire et quand. –

+0

Merci pour votre réponse. Mais je ne comprends pas, pourquoi je ne peux pas accéder aux méthodes dans la classe. Je pensais qu'en définissant la méthode setProperty, cette méthode est effectivement remplacée comme si elle était écrite dans la classe de domaine elle-même. Votre exemple PropertyChecker suggère que je ne peux pas travailler avec un objet réel mais plutôt avec une classe. Malheureusement, cela ne me suffit pas car l'objet lui-même calcule les droits en fonction de son état. Existe-t-il d'autres possibilités pour intercepter l'ensemble et obtenir des appels de propriété? Cordialement, Daniel – Daniel

Questions connexes