Personal tools
Creazione di plugin per gestire gruppi virtuali in Plone

Plone e i gruppi virtuali

Feb 26, 2013

Creazione di plugin per gestire gruppi virtuali in Plone

Una funzionalità Plone che sfrutto pochissimo è il meccanismo dei gruppi virtuali, quello che sta dietro al gruppo "Authenticated User". Analizziamolo!

Poche sono state le volte in cui ho avuto bisogno di sfruttare il gruppo che in Plone è chiamato "Authenticated Users". Si tratta di un gruppo virtuale creato in modo tale per cui ogni utente autenticato risulta appartenere, fra gli altri, a questo gruppo in modo automatico.

E' utile sapere come creare questi gruppi per poterli sfruttare quando si presentano casi d'uso in cui una buona profilazione degli utenti passa per un determinato raggruppamento, soprattutto perché possiamo fare in modo che questo raggruppamento sia automatizzato.

Il caso

Come fa Plone a gestire
i gruppi virtuali??

Partiamo da un caso concreto, al quale sto lavorando in questi giorni. Ci sono degli user che, tramite un sistema di autenticazione federato, si collegano al sito. Quando questi si collegano per la prima volta, viene creato un utente vero e proprio nel sito Plone a cui viene impostata una proprietà (supponiamo sia "caratteristica_x=True"). Devo fare in modo di raggrupparli automaticamente.

In Plone tutto questo si fa con PAS e i suoi plugin in PlonePAS (si può vedere della documentazione qui). E proprio in quest'ultimo troviamo il codice che ci mostra come creare e gestire il gruppo degli "Authenticated User"; codice che si trova nei seguenti file:

  • plugins/autogroup.py
  • __init__.py
  • Extensions/Install.py

Negli ultimi due moduli c'è il codice per registrare il plugin e installarlo. Si tratta di operazioni banali, e ci tornerò sopra più avanti quando mostrerò come creare un nuovo plugin. Nel primo modulo, invece, c'è tutta la logica che riguarda il funzionamento del plugin, ed è questo che mi interessa analizzare.

Analisi del plugin

Il plugin è generato tramite la classe AutoGroup. I meccanismi di PAS si basano sull'implementazione di interfacce tramite cui la classe si impegna a fornire un set di metodi; nella classe in analisi troviamo:

Tramite l'implementazione di interfacce, un plugin fornisce dei metodi e "promette" dei comportamenti
  • IGroupEnumerationPlugin: fornisce metodi per l'enumerazione e la ricerca di gruppi
  • IGroupsPlugin: fornisce un metodo tramite il quale, dato un principal (utente o gruppo) si ritornano tutti i gruppi a cui questo principal appartiene
  • IGroupIntrospection: fornisce metodi per ottenere da un plugin gruppi e utenti dei gruppi
  • IPropertiesPlugin: fornisce un metodo per ottenere le proprietà (titolo e descrizione) di un gruppo.

Per il nostro use case, è tutto corretto e l'unico comportamento che ci interessa modificare è quella fornito da IGroupsPlugin, tramite cui decidiamo se uno user è nel gruppo oppure no.

Creiamo un nuovo plugin

Per farlo, percorriamo i passi già citati sopra:

  • si crea un plugin
  • si registra
  • lo si installa nel sistema.

Come detto, modifichiamo una sola funzionalita, data dal metodo getGroupsForPrincipal:


from App.class_init import InitializeClass from Products.PlonePAS.plugins.autogroup import AutoGroup
from Products.PageTemplates.PageTemplateFile import PageTemplateFile manage_addCustomGroupForm = PageTemplateFile("./zmi/CustomUsersGroupForm", globals())

def manage_addCustomGroup(self, id, title='', group='', description='', RESPONSE=None): """Add an Auto Group plugin.""" plugin = CustomUsersGroup(id, title, group, description) self._setObject(id, plugin) red_to = "%s/manage_workspace?manage_tabs_message=Custom+Users+Group+plugin+added" if RESPONSE is not None: return RESPONSE.redirect(red_to % self.absolute_url())

class CustomUsersGroup(AutoGroup): meta_type = "Custom users group" # IGroupsPlugin implementation. def getGroupsForPrincipal(self, principal, request=None): if principal.getProperty('caratteristica_x'): return (self.group,)
return () InitializeClass(CustomUsersGroup)
 

Gli altri metodi nel codice sopra, manage_addCustomGroup e manage_addCustomGroupForm, sono utilizzati per l'aggiunta e la gestione del plugin in ZMI dentro la acl_users del sito: dobbiamo infatti creare un'istanza del plugin per avere il nuovo gruppo a disposizione.

Una volta scritto il codice del plugin lo dobbiamo registrare nell'inizializzazione del pacchetto:


from Products.PluggableAuthService import registerMultiPlugin

try: registerMultiPlugin(CustomUsersGroup.meta_type) except RuntimeError: # Don't explode upon re-registering the plugin: pass def initialize(context): context.registerClass(CustomUsersGroup, permission=add_user_folders, constructors=(manage_addCustomGroupForm, manage_addCustomGroup), visibility=None )

Fatto questo, possiamo considerare l'attività di sviluppo terminata. Se vogliamo istanziare il plugin con l'installazione del pacchetto, dobbiamo creare un import step dentro il quale fare qualcosa di questo tipo:

 
    ....
    portal = context.getSite()
    acl_users = getToolByName(portal, 'acl_users')
    plugins = acl_users.plugins
    if not 'custom_users_group' in acl_users.objectIds():
        manage_addCustomGroup(acl_users,
                            "custom_users_group",
                            "Custom users (Virtual Group)",
                            "CustomUsersGroup",
                            "Automatic Custom Group Provider")
        for interface in [IGroupsPlugin,
                          IPropertiesPlugin,
                          IGroupEnumerationPlugin,
                          IGroupIntrospection]:
            plugins.activatePlugin(interface, "custom_users_group"
....

In questo modo si aggiunge il plugin alla acl_users del sito e si attivano le interfacce per le funzionalità che il plugin dovrà gestire.

Conclusioni

Finito! Come possiamo vedere a questo punto nella gestione gruppi del sito, abbiamo un gruppo in più, che si comporta esattamente come il gruppo "Authenticated Users", tranne che per la condizione di appartenenza al gruppo; tale gruppo è disponibile anche nello sharing.

Per testarne il funzionamento, possiamo accedere al sito con un utente e verificare che non abbia permessi di nessun tipo. Dalla gestione gruppi possiamo assegnare il ruolo di Manager al gruppo appena creato e tornare a verificare con l'utente di cui sopra, che ora ha permessi da Manager nel portale.

L'immagine in testata è di evildan2

Filed under: , ,
comments powered by Disqus