Accueil > Non classé > Grails – épisode 4 – Utilisation des plugins

Grails – épisode 4 – Utilisation des plugins

Résumé de l’épisode précédent …

L’application est déjà fonctionnelle et entièrement utilisable ! Il est possible de gérer assez facilement sa collection d’album en incluant rapidement des chansons préalablement créés. Mais en l’état actuel, rien n’est sécurisé …

Relire l’article précédent.

Ajout de la sécurité

Pour ajouter la notion de sécurité sur notre application, nous allons piocher dans le formidable réservoir à plugins de Grails.  Vous pouvez consulter la liste des plugins disponibles en tapant cette commande:

1
grails list-plugins

Qu’est ce qu’un plugin Grails ?

Un plugin Grails est une archive au format zip contenant des classes, des taglibs, de nouvelles commandes, et tout un tas d’autres choses diverses et variées (c’est selon le plugin). Lors de l’installation d’un plugin, Grails rapatrie cette archive sur votre machine (en local) et inclut son contenu dans votre application. En quelques secondes, il est possible par exemple:

  • de rajouter la sécurité (il ne restera plus qu’à la configurer)
  • d’intégrer de nouveaux composants Javascripts : utile pour l’IHM
  • d’intégrer un moteur recherche full-text
  • de rajouter l’accès au protocole XMPP (Jabber)
  • et encore bien d’autres choses … je vous laisse consulter la liste

Installation du plugin de sécurité

Pour installer le plugin de sécurité, tapez cette commande:

1
grails install-plugin acegi

Grails installe automatiquement la dernière version disponible sur le dépôt Grails.org.

Le plugin “acegi” ajoute trois nouvelles commandes à l’écosystème de Grails:

  • grails create-auth-domains
  • grails generate-manager
  • grails generate-registration

Nous n’utiliserons que la première. Si vous souhaitez en savoir plus sur les deux autres, je vous invite à consulter la documentation en ligne du plugin: http://grails.org/plugin/acegi

Configuration de la sécurité

Pour commencer, nous allons installer les différents objets du domaine utiles pour la gestion des utilisateurs. Pour cela, nous allons utiliser une des commandes fournies par le plugin:

1
grails create-auth-domains com.excilys.grails.AlbumUser com.excilys.grails.Role Requestmap

Cette commande prend en paramètre:

  • le nom de la classe utilisateur à générer (évitez d’utiliser User car “user” est un mot réservé pour PostGreSQL)
  • le nom de la classe rôle à générer
  • le nom de la classe requestmap à générer

Vous remarquerez que seule la classe RequestMap n’est pas préfixée d’un nom de package. C’est parce que cette classe ne nous servira à rien:  nous allons simplement la supprimer.

1
rm grails-app/domain/Requestmap.groovy

Jetez également un œil sur votre arborescence de fichiers:

  • deux nouveaux contrôleurs ont été ajoutés : LoginController et LogoutController
  • de nouvelles vues ont été ajoutées incluant la vue de login

Maintenant, éditez le fichier grails-app/conf/SecurityConfig.groovy:


1
2
3
4
5
6
7
security {
        active = true
        useRequestMapDomainClass = false
        loginUserDomainClass = "com.excilys.grails.AlbumUser"
        authorityDomainClass = "com.excilys.grails.Role"
        useControllerAnnotations = true
}

Plusieurs paramètres importants sont définis dans ce fichier:

  • active : cette option est assez explicite, elle permet d’indiquer si la sécurité est active … ou pas
  • useRequestMapDomainClass : puisque les Requestmap ne seront pas utilisées, on les désactive
  • loginUserDomainClass et authorityDomainClass permettent d’identifier les classes utilisées pour la sécurité (utilisateur et rôle)
  • useControllerAnnotations : active le mode de sécurité par annotation

Notez bien qu’il existe plusieurs façons de configurer le mode de sécurité:

  • par annotations, c’est celle que je vais vous montrer
  • statique, toutes les URL à protéger sont définis dans le fichier SecurityConfig.groovy
  • stockée en base, les URL sont stockées en base: ce sont les Requestmap

Ok ! La sécurité est installée et quasiment configurée. Lançons notre application:

1
grails run-app

Rendez-vous sur la page d’accueil: http://localhost:8080/albums/ Maintenant, verrouillons …

Verrouillage

Nous voulons que l’interface de création des albums et des chansons soit protégée et réservée aux utilisateurs disposant du rôle d’administration. Le même niveau de sécurité est demandé sur les actions de mise à jour et de suppression. Seules les actions “list” et “show” pourront être publiques (et plus tard l’action “rss”).

Éditez le contrôleur Album ainsi que le contrôleur Song et ajoutez cette annotation en import:

1
import org.codehaus.groovy.grails.plugins.springsecurity.Secured;

Maintenant, pour chacune des actions que nous souhaitons protéger, il suffira d’annoter l’action avec:

1
@Secured(['ROLE_ADMIN'])

Par exemple, l’action “create” sur le contrôleur Album:


1
2
3
4
5
6
7
8
9
@Secured(['ROLE_ADMIN'])
def create = {
    def albumInstance = new Album()
    albumInstance.properties = params

    def availableSongs = Song.findAllByAlbumIsNull()

    return ['albumInstance':albumInstance, 'availableSongs':availableSongs]
}

Essayez maintenant d’accéder à l’écran de création d’un album : http://localhost:8080/albums/album/create

Ecran de login

Écran de login

Voila un bel écran de login mais impossible de se connecter, il n’y a aucun utilisateur en base ! Vous pouvez décider de créer l’interface d’enregistrement (en utilisant une des commandes du plugin : grails generate-registration) ou bien le rajouter à la main ou encore le configurer dans le BootStrap …

Le BootStrap ? késako ?! Ce fichier se situe dans grails-app/conf/. C’est un script Groovy qui s’exécute au moment de l’initialisation ou de la destruction de l’application. Dans ce script vous pouvez décider de créer un ou plusieurs utilisateurs (en faisant quelques vérifications). Exemple:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import com.excilys.grails.*
class BootStrap {

     def init = { servletContext ->

        def myUser = AlbumUser.findByUsername ("grails")
        if (!myUser){
            // l'utilisateur n'existe pas
            // 0b9c2625dc21ef05f6ad4ddf47c5f203837aa32c = toto (SHA1)
            myUser = new AlbumUser ( username:'grails', passwd:'0b9c2625dc21ef05f6ad4ddf47c5f203837aa32c',
                userRealName:'Grails Rocks', email:'grails@excilys.com', enabled:true).save()

            // Ajout du rôle admin pour cet utilisateur
            def role = Role.findByAuthority ("ROLE_ADMIN")
            if (!role){
                role = new Role (authority:'ROLE_ADMIN', description:'Administrateur').save(flush:true)
            }
            // une autre méthode dynamique de Grails, elle permet d'ajouter un
            // objet dans une collection persistée. La collection s'appelle "authorities" et est typée 'Role' dans l'objet myUser
            myUser.addToAuthorities (role)
        }

     }
     def destroy = {

     }
}

Avec ce script, à chaque fois que l’application démarre:

  • on vérifie qu’un utilisateur nommé “grails” existe
  • s’il n’existe pas on le crée, s’il existe on ne fait rien
  • dans le cas où l’utilisateur est fraîchement créé, on lui attribue un rôle nommé ROLE_ADMIN
  • ce rôle est immédiatement créé si non-existant en base

Vous pouvez maintenant vous connecter en utilisant le login grails (mot de passe, ‘toto’).

Ajout des flux RSS

Maintenant que nous savons utiliser les plugins, nous allons les utiliser ! Prenons un autre exemple, le cas des flux RSS:

1
grails install-plugin feeds

Le plugin “feeds” permet d’intégrer l’API Rome à votre application : inclusion des dépendances, mise à disposition de méthodes facilitant l’utilisation de la librairie et taglibs.

Nous allons créer deux flux RSS:

  • sur les albums, le flux récupèrera les 10 derniers albums par ordre de publication
  • sur les chansons, le flux récupèrera les 25 dernières chansons

Le flux album

Editez le controller Album et ajoutez cette action:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
    def rss = {
        // Chargement des albums
        def albums = Album.list(max:10, sort:'dateCreated', order:'desc')

        // la méthode render est disponible sur tous les contrôleurs
        render(feedType:"rss", feedVersion:"2.0") {
            title = "Flux RSS sur les albums" // le titre du flux
            link = createLink (controller:'album', action:'list', absolute:true) // le lien pour aller sur la liste des albums
            description = "Flux RSS sur les albums" // la description globale du flux

            albums.each() { album -> // pour chaque album dans la liste
                entry(album.name) { // créer une entrée
                    link = createLink(controller:'album', action:'show', id:album.id, absolute:true)
                    // le lien de l'entrée (vers le site en absolu)
                    album.description // et le corps de l'entrée
                }
            }
        }
    }

Lancez l’application:

1
grails run-app

Et admirez le résultat :) http://localhost:8080/albums/album/rss

Le flux chanson

Le flux chanson est implémenté de la même façon que celui des albums. Je vous laisse regarder le code source de l’épisode. (cf: ressources)

D’autres plugins …

Bien évidemment le but n’est pas d’énumérer tous les plugins existants. D’autant plus que des plugins que je considère intéressants ne le seront peut-être pas pour vous. Néanmoins, voici une petite liste de plugins que j’ai déjà eu l’occasion d’utiliser (avec plus ou moins de succès):

  • le plugin “searchable”, ajoute la fonctionnalité de recherche full-text en incluant les technologies Compass et Lucène
  • le plugin “auditable”, permet de faire de l’audit sur chacune des opération CRUD des objets du domaine
  • le plugin “xmpp”, pour envoyer des messages Jabber
  • le plugin “mail”, pour envoyer des mails (Javamail)
  • le plugin “quartz”, utile pour intégrer le framework Quartz (déclenchement de Job à intervalle régulier)
  • le plugin “jquery”, pour intégrer JQuery dans votre application
  • et bien d’autres encore (ofchart pour des graphiques en Flash, jcaptcha pour une gestion simple de captcha, …)

Il est important de préciser qu’il faut rester prudent vis-à-vis des plugins : ils ne sont pas toujours adaptés dans le cadre d’un projet professionnel. Et dans certains cas, ils posent plus de problèmes qu’ils n’en résolvent… Un seul conseil (valable en soi pour n’importe quelle technologie) : testez le plugin avant de l’intégrer dans votre projet. Utilisez-le et repérez ces limitations. Un plugin peut-être désinstallé avec cette commande :

1
grails uninstall-plugin PLUGIN_NAME

Gardez bien à l’esprit que le code correspondant à l’intégration du plugin supprimé ne le sera pas (les taglibs dans les vues, les actions dans les contrôleurs, …). Supprimer un plugin bien implenté dans votre application peut donc présenter un coût non négligeable. Les plugins sont à utiliser avec parcimonie donc…

La suite au prochain numéro !!

Dans le prochain numéro nous verrons comment utiliser notre nouvelle application: le packaging et déploiement en prod, la configuration avancée, la notion d’environnement…

Ressources

Code source de l’épisode: albums_episode4.zip
Tag sur le SVN Google Code : http://excilys.googlecode.com/svn/projects/grails-albums/tags/grails-albums_article_4/
Grails et les plugins: http://grails.org/plugin/home
Documentation du plugin acegi: http://grails.org/plugin/acegi
Documentation du plugin feeds: http://grails.org/plugin/feeds

Share
  1. Alexis THOMAS
    06/01/2010 à 09:43 | #1

    Tout continue de rouler parfaitement :)

    à noter quand même la modification à faire dans le Album.groovy de grails-app/domain pour que “sort:dateCreated” ne pose pas problème :

    //Date publication
    Date dateCreated // date autogérée par Grails

    et donc, comme précisé en commentaire, le dateCreated qui fait partie de l’Automatic timestamping de GORM : http://www.grails.org/GORM+-+Events

  1. 18/01/2010 à 15:38 | #1
  2. 20/05/2014 à 01:32 | #2