Personal tools
Quando la sicurezza in Plone è importante: reindexObjectSecurity

Plone e la sicurezza via catalogo

Mar 12, 2013

Quando la sicurezza in Plone è importante: reindexObjectSecurity

Quando gli indici introdotti da prodotti aggiuntivi hanno a che fare con la sicurezza del sito, è meglio prendere alcune precauzioni per evitare problemi

Per chiunque sviluppi con Plone, diventa presto chiara l'importanza del catalogo e, contemporaneamente, la necessità di mantenere il catalogo del sito aggiornato.

L'API principale a cui si fa riferimento per aggiornare lo stato di un contenuto nel catalogo Plone è la chiamata a reindexObject:

>>> context.setTitle('Nuovo titolo')
>>> context.reindexObject()
>>> context.title()
'Nuovo titolo'

Fin qui, nulla di nuovo.

In alcuni casi è possibile limitare gli indici aggiornati a un sottoinsieme di quelli esistenti.

>>> context.setTitle('Nuovo titolo')
>>> context.reindexObject(idxs['Title', 'sortable_title', 'SearchableText'])
>>> context.title()
'Nuovo titolo'

In base all'attributo modificato, vale la pena aggiornare tutti gli indici che lo riguardano.

Quando la sicurezza incontra la ricerca

MeetingUn fatto meno noto: il catalogo di Plone è usato anche nella gestione della sicurezza.
In particolare esiste un indice dal nome allowedRolesAndUsers esplicitamente usato per una verifica di sicurezza: capire se un utente ha accesso a un contenuto (in pratica viene memorizzato nel catalogo se gli utenti hanno il permesso di "View" sul contenuto).

Perché tutto questo? L'alternativa sarebbe disastrosa in termini di prestazioni: caricare tutti i documenti risultanti dalla ricerca e verificare il controllo di sicurezza direttamente su questi.
Tale operazione può diventare molto lenta e dispendiosa, se pensiamo che una semplice ricerca testuale può portare a migliaia di risultati in un sito mediamente popolato.

E' quindi importante che questo indice sia sempre aggiornato. Per questo motivo, ogni volta che viene effettuata un'operazione che comporta un cambio di sicurezza di un contenuto (principalmente modifiche nella pagina di condivisione), l'indice viene aggiornato automaticamente.

Dato che una semplice chiamata al metodo reindexObject può essere relativamente dispendiosa (tenete sempre presente che Plone potrebbe indicizzare anche i file allegati e che l'operazione di re-indicizzazione di un file può essere piuttosto lenta), esiste un altro metodo che viene utilizzata al suo posto: reindexObjectSecurity.
Nel funzionamento base di Plone, questa chiamata si occupa di aggiornare solo l'indice allowedRolesAndUsers introdotto sopra.

Sicurezze alternative

Security camsMa è vero che l'unico indice legato alla sicurezza sia allowedRolesAndUsers?
Nell'uso quotidiano di Plone sì, ma esistono alternative.

Vi porto due esempi.

collective.portlet.truereview

Sto parlando di un prodotto poco noto e di qualche anno fa: collective.portlet.truereview.

Questo prodotto applica lo stesso principio utilizzato col permesso "View" dall'indice allowedRolesAndUsers per un nuovo permesso legato all'attività di revisione dei contenuti: "Review portal content".
Per fare questo viene creato un nuovo indice: reviewerRolesAndUsers.

Lo scopo del prodotto è fornire una portlet di revisione alternativa per Plone che, a differenza di quella ufficiale, non richieda il caricamento del contenuto.
NB: il prodotto è fermo dal 2009, non sono certo che funzioni ancora ma lo trovo piuttosto didattico.

collective.localrolesdatatables

Il secondo esempio è legato al più recente collective.localrolesdatatables.

Questo prodotto vuole fornire una vista che permetta di ispezionare lo stato della sicurezza e delle condivisioni in un sito Plone.
Per fare questo è necessario capire su quali contenuti ci siano effettivamente delle personalizzazioni locali della sicurezza, ovviamente senza caricare i contenuti per non ricadere nel solito problema di prestazioni (ormai ci siamo capiti, vero?!).
L'approccio usato è quello di creare un nuovo indice "hasLocalRoles", un valore booleano che indica se un contenuto ha ruoli locali impostati o meno.

Espandere il funzionamento di reindexObjectSecurity

Universe expandingE' stato proprio utilizzando di recente collective.localrolesdatatables che mi sono imbattuto in un bug (di cui sono certo soffra anche collective.portlet.truereview):
il prodotto funziona a dovere, ma se la sicurezza di un contenuto viene aggiornata, l'indice "hasLocalRoles" non viene modificato a sua volta, almeno non fin quando l'intero documento verrà modificato (e quindi completamente reindicizzato).

Qual è il problema? Il metodo reindexObjectSecurity "non sa" che anche questo indice fa parte della sicurezza del sito.

Come risolvere?

Se andiamo ad analizzare l'implementazione di reindexObjectSecurity, troviamo questa riga di codice:

catalog.reindexObject(ob, idxs=self._cmf_security_indexes,
update_metadata=0, uid=brain_path)

Viene quindi chiesto di reindicizzare nel catalogo il documento (ob) e di limitarsi agli indici definiti nella tupla self._cmf_security_indexes (quindi non tutti gli indici).

_cmf_security_indexes è un attributo di classe definito per CatalogAware, nel pacchetto Products.CMFCore. La sua definizione è la seguente:

_cmf_security_indexes = ('allowedRolesAndUsers',)

La soluzione è molto semplice: estendere la lista di indici registrati in questo attributo (qui come ho modificato collective.localrolesdatatables):

from Products.CMFCore.CMFCatalogAware import CatalogAware

CatalogAware._cmf_security_indexes += ('mioNuovoSecurityIndex',)

Problemi?

Questo tipo di intervento ha un effetto collaterale: modifica l'attributo a livello di classe e si rispecchia quindi su tutti i siti Plone presenti nell'installazione. Potreste anche trovarvi nella situazione in cui il prodotto che necessita di questa modifica sia installato su un solo sito Plone, quindi il nuovo indice non sia presente in altri, eppure la modifica sia comunque applicata.

E' un problema? Per fortuna no!
Il catalogo Plone è molto tollerante: se viene chiesta la reindicizzazione di un indice non esistente, questo fallisce l'operazione senza sollevare eccezioni.

L'immagine di testata è di Alexandre Dulaunoy.

Filed under: , , ,
comments powered by Disqus