Gestire l'Indice delle Pubbliche Amministrazioni del CNIPA
Uno dei prerequisiti per una piattaforma di protocollo informatico CNIPA compliant è la consultazione, quindi la gestione, dei dati presenti all'interno dell'archivio dell'IPA. Questo archivio, basato su Open LDAP 2.0, è un database basato su LDAP che può essere gestito anche all'interno di una custom application, oltre che da normale interfaccia web. A che cosa serve un'archivio nazionale delle Aree Organizzative omogenee della PA? I dati che espone vengono utilizzati, oltre che per attività di Protocollo Informatico, anche per trasmettere via PEC messaggi basati sulla Busta di e-Government, quindi SOAP e Web Services ed altre attività inerenti la comunicazione e l'interoperabilità basata sui servizi. Diciamo, che è il frutto concreto del Nuovo Codice delle Amministrazioni Digitali, ed espone la PA attraverso una vetrina "catalogo" pubblica accedibile via Internet. E' vero, ad oggi solo in parte, che secondo il nuovo codice chiunque invii attarverso un canale di PEC una email ad una PA, quest'ultima è obbligata a conservare, quindi protocollare il messaggio come corrispondenza autentica tra il cittadino e l'amministrazione.... un bel traguardo direte voi!! ma per me che lavoro in questo campo da anni, si tratta solamente di un obiettivo dichiarato nel 2001 e raggiunto, IN PARTE, ad oggi solo da alcune PA :-( Comunque questo requisito rimane e viene descritto nel vecchio documento (check-list) messo a disposizione dal CNIPA anni or sono, ed oggi sono pochissimi i prodotti che inglobano nelle proiprie funzionalità anche quella di creare un bridge di comunicazione da/per l'IPA, in particolare quando si tratta di inviare le comunicazioni ufficiali tra PA e PA attrevrso la PEC. Come se non bastasse c'è ancora molta confusione, su come/quando utilizzare questo strumento per implementare soluzioni compliant ed anche alcune lacune "tecniche" sulla sua implementazione frutto di una scarsa documentazione in merito...fino ad arrivare al punto che alcuni, cercano di nascondere questa funzionalità rimandando parte delle colpe, se pur sacrosante, alla carenza normativa a riguardo. Io da parte mia, ritengo utile almeno condividere un esempio di interrogazione dell'IPA direttamente da codice, con la speranza di chiarire, in parte, alcune ombre sull'utilizzo di questo servizio di ricerca dati. L'esempio che posto, permette dato un indirizzo PEC di ricercare attraverso l'IPA e ritornare un DataSet contenente il profilo della AOO di appartenenza, cosi da poter essere utilizzato al momento che la nostra applicazione decida di convalidare o meno un indirizzo di posta elettronica per la posta in uscita:
Public Function LDAP_SearchAOOByEmail(ByVal email As String) As DataSet
Dim dEntry As DirectoryEntry = Nothing
Dim dSearcher As DirectorySearcher = Nothing
Dim sResults As SearchResultCollection = Nothing
Dim ds As New DataSet
Try
dEntry = New DirectoryEntry
dEntry.AuthenticationType = AuthenticationTypes.Anonymous
dEntry.Path = "LDAP://indicepa.gov.it:389/c=it"
dSearcher = New DirectorySearcher()
dSearcher.SearchRoot = dEntry
dSearcher.Filter = "(&(objectClass=aoo) (mail=" & email & "))"
Dim dt As New DataTable("Table")
dt.Columns.Add(New DataColumn("AOO_name", GetType(System.String)))
dt.Columns.Add(New DataColumn("AOO_description", GetType(System.String)))
dt.Columns.Add(New DataColumn("AOO_email", GetType(System.String)))
dt.Columns.Add(New DataColumn("AOO_nomeResp", GetType(System.String)))
dt.Columns.Add(New DataColumn("AOO_cognomeResp", GetType(System.String)))
dt.Columns.Add(New DataColumn("AOO_mailResp", GetType(System.String)))
sResults = dSearcher.FindAll
If sResults IsNot Nothing Then
For Each sResult As SearchResult In sResults
dt.Rows.Add(sResult.Properties("aoo")(0).ToString, _
sResult.Properties("description")(0).ToString, _
sResult.Properties("mail")(0).ToString, _
sResult.Properties("nomeResp")(0).ToString, _
sResult.Properties("cognomeResp")(0).ToString, _
sResult.Properties("mailResp")(0).ToString)
Next
ds.Tables.Add(dt)
Return ds
Else
Return Nothing
End If
Catch ex As Exception
'Eccezione.
Return Nothing
Finally
If dEntry IsNot Nothing Then dEntry.Dispose() : dEntry = Nothing
If dSearcher IsNot Nothing Then dSearcher.Dispose() : dSearcher = Nothing
If ds IsNot Nothing Then ds.Dispose() : ds = Nothing
End Try
End Function