SlideShare a Scribd company logo
1 of 58
Download to read offline
UNIVERSITÀ DEGLI STUDI DI TRIESTE
Dipartimento di Ingegneria e Architettura
Corso di Studi in Ingegneria Elettronica e Informatica
PROTOTIPAZIONE DI UNA
PIATTAFORMA DI CONTROLLO DEGLI
ACCESSI FISICI CROSS-VENDORS
Tesi di Laurea Magistrale
Laureando:
Massimo PALMISANO
Relatore:
prof. Andrea DE LORENZO
Correlatore:
Francesco DEGRASSI
ANNO ACCADEMICO 2020-2021
Indice
1 Introduzione 4
2 Analisi 6
2.1 Scenario . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.2 Descrizione del problema . . . . . . . . . . . . . . . . . . . . . 7
2.3 Vendors di riferimento . . . . . . . . . . . . . . . . . . . . . . 8
2.4 Tipologia lucchetti . . . . . . . . . . . . . . . . . . . . . . . . 9
2.5 Tipologia credenziali . . . . . . . . . . . . . . . . . . . . . . . 9
2.6 Vendor site . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.7 Definizione requisiti software . . . . . . . . . . . . . . . . . . . 11
3 Progettazione 12
3.1 Modello . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
3.2 Gestione dei diritti utente sui lucchetti . . . . . . . . . . . . . 14
3.3 Modellazione della piantina dell’edificio . . . . . . . . . . . . . 15
3.4 Separation of concerns . . . . . . . . . . . . . . . . . . . . . . 16
3.5 Access Control Logic . . . . . . . . . . . . . . . . . . . . . . . 17
3.6 Hardware Abstraction Layer . . . . . . . . . . . . . . . . . . . 17
3.7 Relazione tra site e vendor site . . . . . . . . . . . . . . . . . . 19
3.8 Limitazioni . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
4 Interfaccia 21
4.1 Installazione e configurazione . . . . . . . . . . . . . . . . . . 21
4.2 Front office . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
4.3 Back office . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
5 Implementazione 26
5.1 Back end . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
1
5.1.1 Strutturazione dei packages . . . . . . . . . . . . . . . 27
5.1.2 Entità principali del modulo HAL . . . . . . . . . . . . 28
5.1.3 Entità principali del modulo ACL . . . . . . . . . . . . 32
5.1.4 Strutturazione del progetto . . . . . . . . . . . . . . . 36
5.1.5 Interazione tra i moduli ACL e HAL . . . . . . . . . . 40
5.1.6 MaintenanceFacade e CoreFacade . . . . . . . . . . . . 40
5.1.7 Gestione delle eccezioni . . . . . . . . . . . . . . . . . . 43
5.1.8 Test . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
5.2 Front end . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
5.2.1 Comunicazione ad eventi tra i componenti . . . . . . . 45
5.2.2 Rappresentazione e costruzione del grafo . . . . . . . . 45
5.3 Estetica delle pagine web . . . . . . . . . . . . . . . . . . . . . 46
5.4 Sistema di controllo di versione . . . . . . . . . . . . . . . . . 46
5.5 Validazione del software . . . . . . . . . . . . . . . . . . . . . 46
6 Conclusioni 54
2
Ai miei genitori
3
Capitolo 1
Introduzione
Il controllo dinamico degli accessi ai grandi ambienti, come un grosso edificio
aziendale, da sempre costituisce un punto di particolare attenzione per le or-
ganizzazioni che li detengono. Questo perché le organizzazioni, come possono
essere le aziende, hanno la necessità di gestire gli spazi interni e limitare gli
accessi alle proprie aree riservate.
L’attuazione di tale controllo è stata per molto tempo difficoltosa, in
quanto gli unici dispositivi a disposizione erano le chiavi e le serrature mec-
caniche tradizionali, le quali male si prestano a molte delle operazioni deside-
rate come la revoca dei permessi o l’accesso a sole determinate fasce orarie ad
una particolare area. I dispositivi che invece bene si prestano a questo com-
pito sono gli smart locks, o lucchetti intelligenti. I vendors di tali dispositivi
sono molti all’interno del mercato, ognuno dei quali presenta ai clienti le pro-
prie soluzioni, non prive però di alcune controindicazioni quali, ad esempio,
l’impossibilità, di fatto, di avere smart locks diversi all’interno del medesimo
edificio e l’obbligo da parte delle organizzazioni a condividere con il vendor
molte delle proprie informazioni interne, come quelle relative ai propri utenti.
La presente tesi prova a dare una risposta ad entrambe le problematiche.
Nello specifico, l’oggetto della tesi è un prototipo di una piattaforma di
controllo e di gestione degli accessi fisici di un edificio, all’interno del quale
possono essere installati degli smart locks. Il lavoro di tesi ha portato alla
produzione di un software, in particolare una applicazione web monolitica
con la quale si può interagire tramite interfacce grafiche.
Gli obiettivi principali che la piattaforma si propone di raggiungere sono
quindi quello di essere cross-vendors - ovvero di garantire la possibilità di
avere all’interno dello stesso edificio smart locks di vendors differenti - e di
4
sollevare le organizzazioni dall’obbligo di condividere le proprie informazioni
interne non necessarie per le meccaniche di controllo degli accessi.
Inoltre, si vuole che la piattaforma esponga le seguenti funzionalità:
• modellazione degli edifici, definendo le stanze e come sono tra loro
collegate
• enumerazione dei percorsi percorribili da un utente, filtrando i risultati
in base a dei criteri predefiniti
• gestione degli utenti e delle credenziali ad essi assegnate
Il progetto è stato proposto dall’azienda di sviluppo software OptionFactory
S.r.l. [19], dove si è svolto sia il lavoro di tesi che il tirocinio. L’idea del
progetto è nata da un dialogo con un cliente, che ha mostrato interesse alla
sua realizzazione. Non nascendo da un progetto preesistente, il prototipo è
stato progettato dal principio: pertanto, salvo diversa indicazione, tutto il
codice cui si fa riferimento è stato scritto dal tesista.
Il codice si articola nel suo front end e nel suo back end, che comprende
una sezione relativa alla persistenza dei dati. Per lo sviluppo del codice
front end si è utilizzato il linguaggio di programmazione JavaScript [13] e il
framework Vue.js [27], mentre per il back end si è utilizzato il linguaggio di
programmazione Java e il framework Spring MVC [24]. Per la persistenza dei
dati si è utilizzato il DBMS relazionale PostgreSQL [21] e Hibernate come
ORM - Object Relational Mapping [11]. Infine, si è utilizzato IntelliJ IDEA
[12] per la scrittura del codice back end e Visual Studio Code [25] per la
scrittura del codice front end.
5
Capitolo 2
Analisi
Nel presente capitolo si descrivono i passi svolti nell’analisi del problema,
partendo dalla raccolta delle informazioni dello scenario di riferimento fino
alla definizione dei requisiti e delle funzionalità del software.
2.1 Scenario
La gestione dinamica del controllo degli accessi alle aree interne di un edificio,
specialmente in ambito aziendale, costituisce da sempre una forte esigenza.
Come è facile intuire, i tradizionali lucchetti e serrature meccaniche rendono
estramemente complesso l’adempimento di tale esigenza: si pensi, ad esem-
pio, alla necessità di elaborare uno storico degli accessi ad un’area riservata
o alla necessità di limitare l’accesso di un utente ad una stanza a predefinite
fasce orarie.
I lucchetti tradizionali quindi male si prestano alla gestione dinamica
del controllo degli accessi. Trovano invece forte impiego in questo scenario
gli smart locks, ovvero dei lucchetti a funzionamento elettromeccanico che
possono essere bloccati o sbloccati presentando loro una credenziale, cioè
un dispositivo autorizzato. Generalmente, lo sblocco avviene soltanto dopo
un’interazione tra il lucchetto e la piattaforma del vendor, che ha effettuato
l’autenticazione dell’utente che ha presentato la credenziale.
Le credenziali possono avere forme e dimensioni molto diverse tra di loro:
sono infatti esempi di credenziali sono i badge, le carte ma anche gli smart-
phone. La comunicazione tra la credenziale e il lucchetto è cifrata, e avviene
6
in modalità wireless. Rispetto ai tradizionali lucchetti meccanici, gli smart
locks consentono la realizzazione di diverse funzionalità, quali
• autorizzazione e autenticazione utente
• gestione delle aree in fasce orarie
• la revoca, o l’assegnazione, del diritto di un utente di poter bloccare, o
sbloccare, un lucchetto da remoto
• raccolta degli accessi
Gli smart locks generalmente sostituiscono le classiche serrature a maniglia,
ma il loro impiego è generale e si possono installare anche su tornelli e cancelli.
Inoltre, possono essere applicati su serrature preesistenti.
In questo settore di mercato si inseriscono molti vendors, che non si limitano
a vendere il singolo smart lock con la chiave ad esso associata, ma forniscono
piuttosto un vero e proprio ecosistema. Esso è molto completo ed espone
molte funzionalità, come la gestione degli utenti e la modellazione degli spazi.
Inoltre, spesso i vendors si occupano anche dell’installazione fisica dei singoli
lucchetti.
2.2 Descrizione del problema
La scelta da parte di una organizzazione di adottare la soluzione di un
vendor non è tuttavia priva di controindicazioni, per cui il rapporto costi-
benefici deve essere valutato attentamente. Sono state analizzate le due
controindicazioni individuate come principali, cui si è cercato di dare una
risposta.
La prima è che le soluzioni proposte dai vendors presuppongono la condi-
visione dei dati interni dell’organizzazione con la loro piattaforma, portando
quindi ad un forte accoppiamento. Quest’ultimo è generalmente fortemen-
te indesiderato, in quanto pur non essendo strettamente necessario obbliga
l’organizzazione a condividere informazioni interne che prerirebbe mantenere
riservate.
La seconda importante controindicazione è che le soluzioni proposte dai
vendors sono non solo verticali ma anche di tipo vendor lock-in, rendendendo
quindi di fatto impraticabile qualsiasi integrazione o coesistenza di soluzioni
7
di vendors diversi. Questo si traduce, ad esempio, nell’impossibilità di avere
lucchetti di vendors differenti all’interno del medesimo edificio. Non solo,
qualora si volesse sostituire la soluzione di un vendor con un’altra, questa
operazione è molto complicata e può avvenire solo ad un costo talmente alto
da portare l’organizzazione alla rinuncia di tale progetto.
2.3 Vendors di riferimento
Uno degli requisiti principali della piattaforma che ci si è proposti di realizzare
è la sua capacità di operare su lucchetti di vendors differenti. Questo com-
porta il disegno di una astrazione uniforme che sia in grado di rappresentare
un generico lucchetto, indipendentemente dal vendor che lo ha fabbricato.
Lo stesso vale per come sono state realizzate le implementazioni relative agli
utenti e ai loro diritti sui vari lucchetti. Per determinare tali astrazioni è
stato perciò necessario la formulazione di un modello che fosse in grado di
rappresentare tutti i modelli dei vari vendors, garantendo l’interoperabilità
e l’apertura all’integrazione. Altrettanto importante è che tale modello sia
sufficientemente generale da essere in grado di rappresentare i vari casi d’uso
di interesse, cercando allo stesso tempo di essere il più semplice possibile.
Per la formulazione del modello stato necessario studiare le soluzioni impie-
gate dai singoli vendors. Tuttavia, nonostante ci siano molti vendors che
operano in questo settore, è stato possibile studiare solo alcune di queste.
Questo è dovuto alla decisione, da parte dei vendors stessi, di mantenere tali
informazioni riservate. Volendo inoltre focalizzare l’attenzione sui vendors
che hanno un peso significativo nel mercato, i vendors principali presi in
considerazione sono stati i seguenti tre
• Salto KS
• OpenPath
• A-Plus
Il livello di dettaglio con cui si sono approfondite tali soluzioni sono diverse,
in base al materiale a disposizione. Si è scelto di studiare la soluzione dell’a-
zienda Salto KS [23] in quanto è leader del mercato [20] e perché il modello
da loro adottato è completo, senza essere eccessivamente complicato.
8
L’azienda OpenPath [18] si è scelta in quanto è quella che presenta una
maggiore apertura all’integrazione e la documentazione è facilmente accessi-
bile. Il modello è il più generale tra quelli che si ha avuto modo di analizzare,
e fornisce il più ricco insieme di funzionalità. Tale modello tuttavia è anche
molto complicato e pieno di dettagli.
Si è scelta infine l’azienda A-Plus [3] in quanto essendoci stati dei contatti
con l’azienda ospitante OptionFactory S.r.l si disponeva della documentazio-
ne non reperibile pubblicamente.
2.4 Tipologia lucchetti
Sul mercato esistono moltissime tipologie di smart locks, che si differenziano
per forma e dimensione. Le più comuni sono tuttavia le seguenti tre (vedi
figura 2.1):
• lucchetto a cilindro
• lucchetto a maniglia
• lucchetto a muro
Figura 2.1: Tipologie comuni di lucchetti offerti dai vendors. Sono riportati
i lucchetti del vendor SALTO KS.
2.5 Tipologia credenziali
Come per le tipologie di lucchetti, anche le credenziali sono molte e diverse fra
loro. Sono esempi di credenziali i badge e le carte, ma anche gli smartphone,
9
i tablet e persino gli smartwatch. In figura 2.2 sono riportate le credenziali
principali del vendor Openpath [18], ma le stesse che si ritrovano in molti
altri vendors.
Figura 2.2: Esempi di credenziali del vendor Openpath. Sono spesso le stesse
di altri vendors.
Le tecnologie più comuni per l’interazione tra esse e i lucchetti sono le
seguenti
• PIN - Personal Identification Number
• BLE - Bluetooth Low Energy
• NFC - Near Field Communication
• RFID - Radio Frequency IDentification
2.6 Vendor site
Per poter utilizzare i lucchetti e le credenziali di un vendor, è prima necessario
associarle all’edificio nel quale verranno impiegate. Tale registrazione avviene
10
nella piattaforma del vendor creando un sito, che corrisponde al concetto di
edificio (caratterizzato da un nome e da indirizzo postale), e associando ad
esso i lucchetti e le credenziali desiderate. Per motivi che saranno chiari in
seguito, si utilizzerà l’espressione vendor site in luogo di sito.
2.7 Definizione requisiti software
Il software che si intende realizzare quindi è una piattaforma di controllo e
di gestione degli accessi fisici, che deve implementare ed esporre le seguenti
funzionalità
• operare su hardware di vendors differenti, offrendo un set di funzionalità
comuni
• esporre funzionalità logiche di alto livello, indipendenti dall’integrazio-
ne hardware, quali
– modellazione degli ambienti e dei varchi che li collegano
– enumerazione dei percorsi disponibili, dato l’insieme di ambienti
cui un utente deve avere accesso
– applicazione di logiche autorizzative, per escludere o limitare i
percorsi disponibili sulla base di proprietà di ambienti e di varchi
– mappatura di utenti e credenziali
• garantire l’allineamento tra il modello astratto e la configurazione in
campo, notificando eventuali scostamenti
• raccogliere eventi dal campo, utilizzati per il controllo di sicurezza,
business intelligence e manutenzione
Gli obiettivi proposti sono
• evitare il vendor lock-in
• separare dati sensibili, aspetti di dominio e identità degli utenti dalle
meccaniche di controllo degli accessi
• garantire l’apertura per l’integrazione in piattaforme di business
11
Capitolo 3
Progettazione
In questo capitolo viene trattato come, a partire dall’analisi, si è arrivati alla
progettazione del software, indicando di volta in volta le scelti progettuali
adottate.
3.1 Modello
Il modello proposto ha come obiettivo quello di fornire un’astrazione ca-
pace di generalizzare tutti i modelli dei vari vendors, mantenendo la capa-
cità di rappresentare tutti i casi d’uso di interesse senza però rinunciare alle
funzionalità che si intende esporre. Esso si fonda sui seguenti concetti chiave
Site
Un sito, o site, rappresenta un edificio fisico caratterizzato da un vero e pro-
prio indirizzo postale su cui è possibile l’installazione di lucchetti di vendors
diversi.
Graph
Il grafo, o graph, rappresenta la piantina di un sito, descrivendo le stanze e
come sono tra loro collegate.
12
Room
Una stanza, o room, rappresenta generalmente una stanza (e.g. l’atrio)
oppure altri spazi o ambienti, come possono essere il corridoio o le scale.
Passage
Un passaggio, o passage, è un’unità di accesso fisico che indica la possibilità
di accedere da una stanza ad un’altra senza passare per stanze intermedie.
Generalmente è una porta, ma può corrispondere ad un cancello o ad un
ascensore. Su di esso possono essere installati più dispositivi, che ne gesti-
scono il blocco e lo sblocco. Il passaggio è inoltre unidirezionale, per poter
modellare situazioni in cui date due stanze è possibile partendo da una acce-
dere all’altra ma non viceversa. Si pensi, a titolo di esempio, ad una porta
antincendio.
Passage Hardware
Con passage hardware si intende l’insieme di dispositivi installati su un pas-
saggio, che ne gestiscono l’apertura e la chiusura. È sufficiente avere i diritti
di sbloccare uno solo di questi per poter percorrere il passaggio. Siccome sul
medesimo passaggio è possibile installare soltanto lucchetti di un medesimo
vendor, che quindi saranno associati al medesimo vendor site, l’identificativo
di un passage hardware è stato costruito concatenando il nome del vendor, il
vendor site id dei lucchetti che compongono il passage hardware e un’ulteriore
stringa, generata internamente:
vendorvendor site idhardware id
Lock
Un lucchetto, o lock, rappresenta un dispositivo in grado di bloccare o sbloc-
care un passaggio. Appartiene ad un solo sito ed è caratterizzato da una
particolare modalità di apertura e dal vendor che lo ha fabbricato.
Credential
Una credenziale, o credential, è qualsiasi dispositivo che un utente può utiliz-
zare per sbloccare un passage hardware. Ogni credenziale è caratterizzata da
13
un protocollo di comunicazione. Sono stati presi in considerazione i protocolli
più comuni quali il PIN, il BLE, l’NFC e l’RFID.
User
Un utente, o user, è una entità che rappresenta un utente dell’organizzazione,
cui possono essere associate una o più credenziali.
Access Group
Un gruppo di accesso, o access group, determina un insieme di utenti e i
lucchetti che possono sbloccare.
Grant
Un grant è un permesso associato ad un site ed è caratterizzato da un periodo
di validità. Definisce quali sono i passaggi che l’utente cui è assegnato ha
accesso.
3.2 Gestione dei diritti utente sui lucchetti
I diritti di un utente su un lucchetto è determinato dagli access group ai quali
appartiene. In particolare, un utente u può aprire un lucchetto l se e solo se
appartiene ad almeno un access group ag tale che abbia il diritto di aprire il
lucchetto l.
Per implementare la gestione del controllo degli accessi quindi bisogna
determinare una strategia riguardo la gestione degli access groups. Ne sono
state individuate tre:
1. un access group per utente
2. un access group per lucchetto
3. un access group per percorso
Per la sua semplicità e flessibilità, la strategia che si è deciso di impiegare è
la stretegia numero 2. In questo modo qualora si volesse dare ad un utente u
l’accesso ad un lucchetto l è sufficiente aggiungerlo all’access group ag relativo
14
a l. Analogamente, qualora si volesse revocare tale diritto, sarebbe sufficien-
te rimuovere u da ag. In questo modo inoltre, qualora si volesse sostituire
il lucchetto di un passage con un altro (e.g. per un guasto), sarebbe suffi-
ciente sostituire il lucchetto dell’access group con quello nuovo. La strategia
tuttavia introduce un alto numero di access group: uno per lucchetto.
3.3 Modellazione della piantina dell’edificio
Si è deciso di modellare la cartina del building con un grafo bidirezionale,
dove ogni nodo è una stanza e ogni arco è un passaggio (vedi figura 3.2). In
ogni grafo è sempre presente un nodo denominato outside, che rappresenta il
mondo esterno dal quale si accede all’edificio.
Si prenda a titolo di esempio la piantina di figura 3.1.
Meeting Room
Hall
Office
Bathroom hallway
Figura 3.1: Esempio cartina di un edificio
Il grafo equivalente è quindi costituito da sei nodi. Quattro di essi rap-
presentano le stanze hall, bathroom, meeting room e office, mentre i restanti
15
due sono usati per rappresentare l’ambiente esterno e il corridoio hallway. Il
grafo che si ottiene a partire dalla cartina di figura 3.1 è rappresentato in
figura 3.2.
outside
hall
hallway bathroom
meeting
room
office
Figura 3.2: Grafo equivalente della cartina di figura 3.1
3.4 Separation of concerns
Per poter realizzare le funzionalità desiderate, il middleware deve comunicare
con le piattaforme dei singoli vendors. Tuttavia, questa necessità è ortogonale
alla logica di business dell’applicazione. Si è deciso allora di suddividere il
middleware in due layers: il primo, che opera a livello logico più alto, si
occupa di realizzare la business logic e si appoggia al secondo layer, che
opera invece ad un livello logico più basso e si occupa di dialogare con le
16
piattaforme dei singoli vendors, fornendo al layer soprastante un’interfaccia
uniforme. Definiamo allora Access Control Logic - ACL il layer di più
alto livello e Hardware Abstraction Layer - HAL il layer di livello più
basso (vedi figura 3.3).
Access Control Logic
Hardware Abstraction Layer
Middleware
Figura 3.3: I due layer di cui si compone il middleware: l’Access Control
Logic e l’Hardware Abstraction Layer
3.5 Access Control Logic
L’Access Control Logic è il modulo che si occupa della logica di business
dell’applicazione, esponendone tutte le funzionalità. Gli utenti finali sono
due: i manutentori, che si occupano della installazione dei lucchetti e del-
la costruzione della cartina dell’edificio, e il personale della reception, che
invece si occupa dell’assegnazione delle credenziali e dei diritti agli utenti
dell’organizzazione.
Per ciascun attore si vuole fornire una interfaccia da cui saranno fruibili
le funzionalità di cui ha bisogno. Una è quindi dedicata al back office, la
seconda invece è dedicata al front office. Siccome tali interfacce espongono
funzionalità in generale diverse pur appoggiandosi allo stesso modulo, si è
deciso di seguire il facade design pattern, e quindi scrivere una facade per
insieme di funzionalità. Le due facade sono state denominate Core Facade
e Maintenance Facade (vedi figura 3.4), che quindi sono parte integrante
dell’ACL.
3.6 Hardware Abstraction Layer
L’Hardware Abstraction Layer deve fornire all’Access Control Logic una
astrazione che sia indipendente dal particolare vendor sottostante, e quindi
17
Access Control Logic
Maintenance Facade
Core Facade
Front Office Back Office
Figura 3.4: L’Access Control Logic si interfaccia con due facade: la Core
Facade e la Maintenance Facade
l’interfaccia che espone deve essere uniforme. Per realizzare tale astrazione
al suo interno l’HAL si compone di diversi driver, uno per vendor (vedi fi-
gura 3.5). Le varie richieste che l’HAL riceverà saranno quindi smistate e
indirizzate al driver del vendor opportuno. In questo modo si riesce ad essere
aperti all’integrazione: qualora si volesse aggiungere il supporto ai lucchetti
di un altro vendor sarà sufficiente implementare il driver corrispondente.
Hardware Abstraction Layer
Driver Vendor 1 Driver Vendor 2 ...
Figura 3.5: L’hardware abstraction layer si appoggia ai driver che si occupano
di interagire con la piattaforma del vendor corrispondente
18
3.7 Relazione tra site e vendor site
Nel modello, un sito può ospitare al suo interno lucchetti di vendors differenti,
che sono associati ad un vendor site (vedi paragrafo ...). Questo significa che
un sito è associato a sua volta a tanti vendor sites quanti sono i vendors
differenti dei lucchetti che ospita. Sussiste una relazione quindi uno a molti
(vedi figura 3.6). Siccome in generale è possibile due vendor site di vendors
diversi abbiano lo stesso id, per identificare univocamente un vendor site si
è costruita una stringa come segue
vendor namevendor site id
cui diamo il nome, per motivi che saranno chiari in seguito, hal site id. Infine,
per distinguere i siti definiti all’interno dell’ACL da quelli dei vari vendors,
denotiamo i primi acl site e i secondi vendor site.
acl site
vendor site 1 vendor site 2 vendor site 3
Figura 3.6: Un acl site può essere associato a più vendor site
3.8 Limitazioni
Alcune operazioni di interesse, come la registrazione di un lock o di una
credenziale ad un vendor site, non sono state automatizzate. Questo perché
tali operazioni prevedono molti passaggi, alcuni dei quali per loro natura sono
di difficile automatizzazione. Non solo, l’automatizzazione di tali procedure
è resa complessa a causa della eterogeneità delle procedure previste dalle
piattaforme dei vendors. Per questi motivi si è lasciato agli operatori il
compito di svolgere manualmente le procedure previste dalle piattaforme dei
vari vendors.
19
A titolo di esempio, si consideri la procedura prevista dal vendor SALTO
KS per l’associazione di un badge ad un suo vendor site. Essa prevede di
avvicinare il badge ad un lucchetto posto in modalità registrazione, cui se-
guirà un segnale sonoro che indica la corretta associazione della credenziale
al medesimo vendor site del lucchetto. Si evince facilmente quindi che tale
operazione per sua natura non è automatizzabile.
20
Capitolo 4
Interfaccia
Come anticipato nei capitoli precedenti, l’interfaccia si compone di due ap-
plicazioni web. Una è dedicata al back office, come i manutentori, l’altra al
front office, ovvero il personale della reception.
4.1 Installazione e configurazione
Per utilizzare il software è necessario avviare l’applicazione web. Il server
è configurato per eseguire il binding sulla porta 8080 della macchina locale
sulla quale viene avviato.
4.2 Front office
Per accedere all’interfaccia del front office, si apra un browser e si navighi
all’indirizzo
http://hostname :8080/core/site id
La pagina web si compone di diversi tabs, di cui il primo è quello mostrato
di default e consiste in una pagina di benvenuto (vedi figura 4.1). Questa
mostra alcune informazioni generali dell’edificio, come il numero di stanze e
di passaggi di cui si compone.
Il secondo tab invece consente di gestire i permessi assegnati ai vari utenti
dell’organizzazione tramite una tabella, che prende il nome di Grants Table
(vedi figura 4.2). Ogni riga di cui si compone corrisponde quindi ad un grant,
21
Figura 4.1: pagina di benvenuto del front office
in cui vengono mostrate le relative informazioni quali l’utente cui è assegnato,
il sito cui fa riferimento, i passaggi che può sbloccare e il periodo di validità
dello stesso. Inoltre, nell’ultima cella è presente un bottone che ne consente
la revoca.
Figura 4.2: tab che mostra una tabella contenente i grants
Il terzo tab infine consente di assegnare i grants agli utenti della organizza-
zione. Sulla sinistra viene mostrato un form, mentre sulla destra invece viene
mostrata la cartina dell’edificio sotto forma di grafo. Per assegnare un nuovo
grant è necessario compilare i campi del form, che si articolano in
22
• stanza di partenza
• stanza di arrivo
• percorsi possibili
• utente cui assegnare il grant
• data inizio validità del grant
• data fine validità del grant
Una volta indicata la stanza di partenza e di arrivo, vengono mostrati i
percorsi possibili che è possibile assegnare elencando le stanze da percorrere.
Per rendere più immediato quale siano le stanze di cui è costituito il percorso
scelto, i nodi e gli archi che non sono coinvolti assumono una colorazione
grigia, in modo da rendere più evidente all’operatore il percorso che sta per
assegnare all’utente (vedi figura 4.3).
Figura 4.3: Screenshot del tab ”Create Grant”
23
4.3 Back office
Per accedere all’applicazione web relativa al back office si navighi all’indirizzo
url
http://hostname :8080/maintenance/site id
Il sito web si compone di due tab. Il secondo è composto di due tabelle:
la prima mostra i siti dei vendors attualmente associati al sito, la seconda
invece quelli per cui non è presente alcuna associazione e che quindi possono
essere associati (vedi figura 4.4).
Figura 4.4: Screenshot del tab ”vendor sites”
Il primo tab invece, mostrato di default, è relativo alla cartina dell’edificio,
dove vengono in particolare mostrati tre form e la mappa della cartina stessa,
anche qui sotto forma di grafo (vedi figura 4.5). Gli archi del grafo mostrano,
qualora presenti dei lucchetti installati su di essi, le modalità di sblocco per
passare il passaggio stesso.
Il form ”Add Room” consente di aggiungere una stanza alla piantina,
specificando il nome della stessa. È inoltre possibile assegnare alla stanza
alcuni attributi, indicati come checkboxes (e.g. se è un’area riservata). La
stanza creata costituisce inizialmente un nodo isolato, ma può essere connesso
agli altri successivamente.
Il form ”Add Passage” invece consente di aggiungere un passaggio speci-
ficando la coppia di stanze che connette. Essendo i passaggi monodirezionali,
24
l’ordine delle stanze è rilevante. È comune che qualora esista un passaggio tra
due stanze, esso sia bidirezionale. Per migliorare l’esperienza utente, contras-
segnando il checkbox ”bidirectional” vengono creati direttamente entrambi i
passaggi.
Infine, il form ”Add Lock” consente di aggiungere un lucchetto ad un
passaggio, scegliendo tra i vendor sites associati al sito corrente. Una volta
aggiunto, comparirà il vendor del lucchetto nel passaggio indicato.
Figura 4.5: Screenshot del tab ”building map”
25
Capitolo 5
Implementazione
L’implementazione del progetto si articola nella realizzazione del suo back
end e del suo front end. Si è sviluppato il progetto seguendo la metodologia
agile, i cui principi sono indicati nel suo manifesto [17].
All’interno del capitolo sono presenti alcuni diagrammi di classe UML
delle entità che compongono il progetto. Lo scopo di tali diagrammi è quello
di rendere la trattazione maggiormente chiara piuttosto che dare una descri-
zione dettagliata ed esaustiva delle entità che descrivono. Per questo motivo,
alcuni campi o metodi potrebbero essere omessi per meglio mettere in luce
quelli di maggiore interesse alla trattazione.
Sempre per rendere la trattazione più chiara possibile, all’interno del ca-
pitolo sono stati anche riportati alcuni frammenti di codice per la descrizione
di metodi e interfacce. All’interno degli stessi alcune parti potrebbero essere
omesse, per rendere il codice meno verboso e più significativo ai fini della
trattazione.
5.1 Back end
Il codice è stato scritto all’interno del framework Spring MVC [24]. Esso
si articola in due moduli: l’Access Control Logic e l’Hardware Abstraction
Layer, entrambi inseriti nel package net.opfa. La scelta del linguaggio di
programmazione per la scrittura di entrambi i moduli è quindi ricaduta su
Java, nella sua versione 17.
Per eseguire il build del progetto sono necessari diversi steps, come la
compilazione del codice sorgente, l’esecuzione dei test automatizzati e del
26
packaging dell’applicazione. Per questi tasks si è utilizzato Apache Maven,
un software project management e un comprehension tool [1].
Il web server è stato esteso con l’architettura delle Java Servlet, che pre-
vede l’impiego di un servlet container, ovvero di un programma specifico che
mette a disposizione un ambiente ricco di funzionalità sfruttabili per la scrit-
tura di programmi Java per il calcolo dinamico delle pagine, che prendono il
nome di servlet. Il servlet container utilizzato è Apache Tomcat, un software
open source che implementa alcune specifiche della piattaforma Jakarta EE
[2]. La versione utilizzata è la 9.0.56.
5.1.1 Strutturazione dei packages
Tutto il codice è all’interno del root package net.opfa. Per la suddivisione
dello stesso erano possibili due strategie: la strutturazione per feature, o
verticale, che prevede un package per ogni singola feature, e la strutturazione
per layer, o orizzontale, che invece prevede tanti livelli di packages quanti
sono i livelli in cui è strutturata l’applicazione. Siccome un criterio non è
necessariamente migliore dell’altro, si è scelta la strutturazione per layer per
comodità.
net.opfa acl
exceptions
common
configuration
hal
controllers
core
maintenance
drivers
Figura 5.1: organizzazione dei packages per layer; non esaustiva
Il package net.opfa.common contiene tutte le classi comuni all’intera ap-
plicazione come la classe Credential o la classe Vendor. Le classi neces-
sarie per la corretta configurazione di Spring MVC come la configurazione
del DBMS e dei controllers invece sono stati inseriti all’interno del package
net.opfa.configuration. Infine, nel package net.opfa.vendors sono sta-
te inserite le classi dei vari drivers, sebbene al momento si compone di un
solo package, contenente le classi del driver per il vendor SALTO KS [23].
27
5.1.2 Entità principali del modulo HAL
In questa sezione si elencano le entità principali del modulo Hardware Ab-
straction Layer, concludendo con la stesura del relativo schema E-R.
Passage Hardware
Il concetto di passage hardware è implementato dalla classe PassageHardware
(vedi figura 5.2). Siccome ad un passage hardware è possibile aggiungere, o
togliere, un lucchetto dinamicamente nel tempo, sono previsti dei metodi che
adempiano a tali operazioni. Inoltre, i lucchetti che lo compongono determi-
nano le modalità di apertura del passage hardware. Infine, siccome a partire
dall’id si possono ottenere informazioni utili come il vendor site id, sono stati
scritti dei metodi statici per eseguirne il parsing.
PassageHardware
+ String id
+ Set<CredentialTypes> unlockModes
+ Set<String> lockIds
+ addLocks()
+ removeLocks()
+ getHalSiteId()
+ getVendoSiteId()
+ getVendor()
+ getHardwareId()
Figura 5.2: Diagramma delle classi UML per la classe PassageHardware
Lock
La classe Lock rappresenta il concetto di lucchetto ed è quindi caratterizzato
dal particolare venditore che lo ha fabbricato, la sua modalità di sblocco, il
suo identificativo e una descrizione dello stesso, che servirà al manutentore
per accertarsi che il lucchetto sta aggiungendo ad un passaggio sia lo stesso
che ha installato.
28
Ad esempio, nel caso dell’installazione di un lucchetto del vendor SALTO
KS, la descrizione di un lock è il suo activation code, una stringa univoca
di caratteri sovra impressi fisicamente sul lucchetto. Quindi, quando un
manutentore vuole indicare che in un certo passaggio è stato aggiunto quel
lucchetto, gli sarà sufficiente selezionare il lucchetto caratterizzato da quel
particolare activation code.
L’identificativo del lock è una stringa che contiene informazioni relativa-
mente al venditore, all’identificativo del sito del venditore cui appartiene e
dall’identificativo proprio del lucchetto dato dal venditore. Analogamente
all’id della classe PassageHardware, l’id di un lock si è costruito come
vendorvendor site idvendor lock id
La classe risultante è riportata in figura 5.3
Lock
+ String id
+ String description
+ CredentialType lockType
+ getVendor()
+ getVendorSiteId()
+ getVendorLockId()
+ buildLockId()
Figura 5.3: Diagramma delle classi UML per la classe Lock
Desired State
Per fare in modo che il modello astratto si concretizzi nel mondo reale, è ne-
cessario effettuare le opportune operazioni sulle piattaforme dei vari vendors,
di cui si occuperà l’HAL. A tale scopo due approcci sono possibili: l’approccio
imperativo, per il quale l’ACL indica all’HAL le singole operazioni in modo
puntuale che deve eseguire, oppure l’approccio funzionale, per il quale l’ACL
passerà all’HAL lo stato desiderato atteso che quest’ultimo dovrà tradurre
nelle corrispondenti operazioni.
29
Il concetto di stato atteso è implementato dalla classe DesiredState, che
ha al suo interno una mappa che tiene traccia lo stato atteso di ogni utente
(vedi figura 5.4)
DesiredState
+ Map<String, UserDesiredState> desiredStateMap
+ isEmpty()
+ addUserDesiredState()
Figura 5.4: Diagramma delle classi UML per la classe DesiredState
Lo stato atteso di ogni utente è implementato dalla classe UserDesiredState,
che definisce per ogni utente i passage hardware che deve essere in grado di
aprire a partire dalle sue credenziali.
UserDesiredState
+ String aclUserId
+ Set<String> passageHardwareIds
+ Set<Credential> userCredentials
+ isEmpty()
Figura 5.5: Diagramma delle classi UML per la classe UserDesiredState
Il metodo che si occupa di calcolare lo stato atteso è computeDesiredState()
(vedi listato 5.1), che utilizza il metodo computeUserDesiredState() (vedi
listato 5.2).
@Override
public DesiredState computeDesiredState() {
final DesiredState desiredState = new DesiredState();
30
final Set<AclUser> aclUsers = aclUsersRepository.findAllUsers();
aclUsers
.stream()
.map(AclUser::getId)
.map(this::computeUserDesiredState)
.forEach(desiredState::addUserDesiredState);
return desiredState;
}
Listato 5.1: Metodo che si occupa di calcolare lo stato atteso
Il metodo computeUserDesiredState() determina quali sono i passaggi che
un utente deve essere in grado di aprire a partire dai grants ad esso associati.
@Transactional
@Override
public UserDesiredState computeUserDesiredState(String aclUserId) {
final Set<Grant> grants = grantsRepository.findUserGrants(aclUserId);
final AclUser aclUser = aclUsersRepository.findUserById(aclUserId)
.orElseThrow(AclUserNotFoundException::new);
if (grants.size() == 0) {
return new UserDesiredState(
aclUserId,
new HashSet<>(),
aclUser.getCredentials());
} else {
final String aclSiteId = grants
.stream()
.findFirst()
.get()
.getAclSiteId();
return computeUserDesiredState(aclSiteId, aclUserId);
}
}
Listato 5.2: Metodo che si occupa di calcolare lo stato atteso di ogni utente
31
Schema E-R
Lo schema E-R del modulo HAL è quindi molto semplice (vedi figura 5.6).
Per mantenere il modulo ACL con il modulo HAL il più disaccoppiati pos-
sibile, all’interno di quest’ultimo non vi è alcun riferimento ai passaggi cui i
passage hardware sono associati.
Passage Hardware appartenenza Lock
(1,1)
(1,N)
Figura 5.6: Schema E-R modulo HAL
5.1.3 Entità principali del modulo ACL
Come per il modulo HAL, in questa sezione sono descritte le entità principali
del modulo ACL, concludendo con la descrizione del relativo schema E-R.
Room
La classe Room rappresenta il corrispondente concetto di room e costituisce
un nodo del grafo. Essa è caratterizzata da un id e da alcuni metadati, come
il nome della stanza stessa.
Passage
La classe Passage rappresenta il corrispondente concetto di passage e costi-
tuisce gli archi del grafo. Anch’esso è caratterizzato da un id come la classe
Room. Inoltre, se presente, presenta come attributo una stringa che indica
qual è il passage hardware id installato. Siccome tale parametro è opzionale,
il getter non si limita a restituire la stringa, ma la avvolge in un wrapper
java.util.Optional (vedi listato 5.3).
public Optional<String> getPassageHardwareId() {
return Optional.ofNullable(this.passageHardwareId);
}
Listato 5.3: getter della classe PassageHardware
32
AclSite
La classe AclSite rappresenta il corrispondente concetto di site, ed è quindi
caratterizzata da un id, un nome, un indirizzo postale e un grafo che ne
modella la cartina.
Il grafo e le operazioni ad esso associate sono state implementate ricorren-
do a JGrapht, una libreria java di strutture dati e algoritmi della teoria dei
grafi [14]. La libreria offre molte implementazioni della struttura dati grafo,
tante quante le particolari tipologie dello stesso (e.g. grafo diretto aciclico,
grafo direzionato, multigrafo). La classe che si adatta al nostro caso d’uso è
la classe org.jgrapht.graph.DirectedPseudoGraph, ovvero un’implemen-
tazione di un pseudografo direzionato che consente di utilizzare una qualsiasi
classe sia per i vertici che per gli archi. I nodi quindi saranno istanze della
classe Room, mentre gli archi saranno istanze della classe Passage. Esso può
avere uno o più hal site id, che identificano i vendor site cui sono associati.
La classe risultante è riportata in figura 5.7.
AclSite
+ String id
+ String name
+ String address
+ Set<String> halSiteIds
+ addRoom()
+ addPassage()
+ removePassage()
+ removeRoom()
+ getOutside()
+ addHalSiteId()
+ getHalSiteIds()
Figura 5.7: Diagramma di classe UML della classe AclSite
33
Path
Si è deciso di rappresentare il concetto di percorso, o path, come una sequen-
za ordinata di passaggi. Non esiste una vera e propria classe Path, in quanto
non sarebbe stata altro che un wrapper di List<String> passageIds, ov-
vero una sequenza ordinata di stringhe, ognuna delle quali identificante un
passaggio del grafo. Non è possibile rappresentare un percorso come sequenza
di stanze in quanto in base al nostro modello in generale è possibile passare
da una stanza all’altra con passaggi diversi, che possono avere lucchetti di
vendors diversi. Nel modello utilizzato pertanto dati due passaggi che han-
no la medesima stanza di partenza e di arrivo, un utente potrebbe essere in
grado di percorrere uno ma non l’altro.
Partendo da una coppia di stanze e dal loro sito di appartenenza il metodo
findAllPaths() trova l’insieme di tutti i percorsi possibili (vedi listato 5.4).
Per determinarli viene fatto uso della classe AllDirectedPath, una classe
del package org.jgrapht.alg.shortestpath definita nella libreria jgrapht.
La classe è un algoritmo Dijkstra-like, che determina tutti i percorsi tra due
insiemi di nodi in un grafo direzionato, con l’opzione di cercare soltanto i
percorsi semplici e limitare la lunghezza del percorso.
private Set<List<String>> findAllPaths(
AclSite aclSite,
Room startRoom,
Room destinationRoom) {
final AllDirectedPaths<Room, Passage> allPaths = new
AllDirectedPaths<>(aclSite.getGraph());
return allPaths
.getAllPaths(startRoom, destinationRoom, true, Integer.MAX_VALUE)
.stream()
.map(path -> path
.getEdgeList()
.stream()
.map(Passage::getId)
.collect(Collectors.toList()))
.collect(Collectors.toSet());
}
Listato 5.4: Metodo per determinare tutti i percorsi possibili (semplici) data
una coppia di stanze
34
Credential
La classe credential rappresenta il corrispondente concetto di credential ed
è stato implementato come value type, ovvero un oggetto privo di identifica-
tivo. I campi di tale oggetto sono la sua tipologia (e.g. BLE, NFC) e il valore
numerico al suo interno, che verrà scansionato dal lucchetto al quale viene
presentata. L’oggetto Credential quindi non rappresenta la credenziale di
questo o quel vendor. La classe risultante è rappresentata in figura 5.8.
Credential
+ CredentialType credentialType
+ String value
Figura 5.8: Diagramma delle classi UML per la classe Credential
AclUser
Un AclUser è un placeholder che ha la sola funzione di rappresentare un
utente dell’organizzazione, senza però alcuna informazione aggiuntiva. In
questo modo si evita che l’organizzazione condivida alcuna informazione in-
terna. Le uniche informazioni di un utente acl quindi sono le credenziali che
esso possiede (vedi figura 5.9).
AclUser
+ String id
+ Set<Credential> credentials
Figura 5.9: Diagramma delle classi UML per la classe AclUser
Schema E-R
Lo schema E-R risultante del modulo ACL è riportato in figura 5.10
35
Sito generazione
Grant
(1,1)
(1,1)
appartenenza
(0, N)
Utente
(1, N)
assegnazione
(1, 1)
(0, N)
ownership
(0, N)
Credential
(1, 1)
Figura 5.10: Schema E-R del modulo ACL
5.1.4 Strutturazione del progetto
L’architettura scelta per la strutturazione di entrambi i moduli è una strut-
tura che si articola in diversi layer (vedi figura 5.11).
APIs
Nel caso del modulo ACL, le sue funzionalità sono esposte tramite dei servizi
web, implementati seguendo il pattern dei RESTful Web Services [22]. Per la
loro creazione si sono utilizzati gli spring rest controllers, che si occupano di
mappare le richieste ai metodi corrispondenti. Il formato scelto dell’oggetto
restituito è il formato JSON [15].
Le APIs esposte si possono raggruppare concettualmente in due insiemi:
quelle dedicate al front office e quelle dedicate al back office. I primi sono
36
APIs
Facade
Repositories
Database
Figura 5.11: Architettura progetto
mappati all’indirizzo url http://hostname /core/*, i secondi all’indirizzo
http://hostname /maintenance/*. Per ciascun insieme sono stati scritti
due controllers: il CoreController e il MaintenanceController, entrambi
inseriti nel package net.opfa.controllers.
@RestController
public class MaintenanceController {
@Autowired
MaintenanceFacade maintenanceFacade;
// seguono altri metodi
}
Listato 5.5: Definizione MaintenanceController
Ogni controller ha un metodo che cattura un’eventuale eccezione che si
dovesse verificare all’interno del codice: tale metodo è stato denominato
catchNotFoundException ed è stato annotato con @ExceptionHandler (ve-
di listato 5.6).
@ResponseStatus(HttpStatus.NOT_FOUND)
@ExceptionHandler(value = {
RoomNotFoundException.class,
AclUserNotFoundException.class,
AclSiteNotFoundException.class,
PassageNotFoundException.class,
})
public String catchNotFoundException(RuntimeException exception) {
37
return exception.getMessage();
}
Listato 5.6: Definizione dell’exception handler
Il modulo Hardware Abstraction Layer invece essendo interno al progetto
espone le APIs come semplici metodi java, che l’Access Control Logic può in-
vocare. Tali metodi sono definiti nell’interfaccia HalApi, presente nel package
net.opfa.hal (vedi listato 5.7).
public interface HalApi {
List<Lock> listAllVendorLocks(Set<String> halSiteIds);
boolean isLockRegistered(String halSiteId, String lockId);
boolean isLockRegistered(Set<String> halSiteIds, String lockId);
List<HalSiteDto> fetchHalSites ();
Set<CredentialType> findCredentialTypesForPassageHardwareSet(
Set<String> passageHardwareIds);
Set<CredentialType> findCredentialTypesForPassageHardware(
String passageHardwareId);
void applyUserDesiredState(UserDesiredState userDesiredState);
Set<Credential> loadUserCredentials(
String externalUserId,
Set<String> halSiteIds);
boolean canUnlockPassageHardware(
String aclUserId,
String passageHardwareId,
Set<Credential> userCredentials);
String createPassageHardware(
Vendor vendor,
String vendorSiteId,
String lockId);
void addLockToPassageHardware(
String passageHardwareId,
38
Vendor vendor,
String lockId);
}
Listato 5.7: Metodi di HalApi
Facade Pattern
Si è adottato come design pattern strutturale il facade pattern, che fornisce
una interfaccia semplificata ad una libreria, a un framework o a un qualche
insieme complesso di classi [9].
I controllers perciò non implementano alcuna logica di business (vedi lista-
to 5.8), tale responsabilità è infatti affidata alle facade MaintenanceFacade
e CoreFacade.
@PostMapping(value = "/maintenance/sites")
@ResponseStatus(HttpStatus.CREATED)
public CreateAclSiteResponse createAclSite(
@RequestBody CreateAclSiteRequest createAclSiteRequest) {
return maintenanceFacade.createAclSite(
createAclSiteRequest.getAclSiteName(),
createAclSiteRequest.getAclSiteAddress());
}
Listato 5.8: Metodo di un rest controller. Come si evince facilmente, non
implementa alcuna logica di business
Repositories
Le classi MaintenanceFacade, CoreFacade e HalApi hanno le proprie repo-
sitories, ovvero classi il cui obiettivo è quello di fornire una API pulita per
l’accesso ai dati, salvati nel DBMS.
Database
Per la scrittura del database si è utilizzato il DBMS PostgreSQL, un database
object-relational opensource [21] nella sua versione 14.1. Per convertire le
39
righe delle tabelle in oggetti Java e per poterli manipolare si è utilizzato
l’ORM - Object Relation Mapping Hibernate, nella sua versione 5.6.1 [11].
Per mantenere i due moduli disaccoppiati, ognuno gestisce autonomamente
le proprie entità, che sono salvate in tabelle scollegate tra loro.
5.1.5 Interazione tra i moduli ACL e HAL
I concetti che sono in comune ad entrambi, che ne constuiscono quindi il
vocabolario comune, sono i seguenti
• String passageHardwareId
• UserDesiredState userDesiredState
• String halSiteId
Access Control Logic
Hardware Abstraction Layer
User Desired State Passage Hardware Id Hal Site Id
Figura 5.12: Vocabolario condiviso tra HAL e ACL
Per fare in modo che i moduli siano più disaccoppiati possibile, il modulo
HAL, lavorando ad un livello di astrazione più basso, non ha al suo interno
alcun concetto di più alto livello che invece è proprio dell’ACL.
5.1.6 MaintenanceFacade e CoreFacade
Le facade MaintenanceFacade e CoreFacade sono in particolare due interfac-
ce, implementate rispettivamente dalle classi DefaultMaintenanceFacade e
DefaultCoreFacade. Tutte queste classi si trovano all’interno del package
40
net.opfa.acl.maintenance. Il codice delle interfacce è riportato nel listato
5.10 e nel listato 5.9.
public interface MaintenanceFacade {
MaintenanceGraphResponse fetchGraph(String aclSiteId);
CreateAclSiteResponse createAclSite(String siteName, String address);
CreateRoomResponse createRoom(String aclSiteId, String roomName);
CoreRoomResponse deleteRoom(String aclSiteId, String roomId);
MaintenancePassageResponse createPassage(String aclSiteId, String
startingRoomId, String targetRoomId);
CorePassageResponse deletePassage(String aclSiteId, String passageId);
AddLockResponse registerLock(String aclSiteId, String passageId,
Vendor vendor, String vendorLockId);
boolean addVendorSiteToAclSite(String aclSiteId, String vendorSiteId,
Vendor vendor, String customerReference);
List<HalSiteDto> fetchHalSites(String aclSiteId);
List<HalSiteDto> fetchHalSitesNotAssigned();
List<LockResponse> fetchAllVendorLocks(String aclSiteId);
boolean existsRoom(String aclSiteId, String roomId);
boolean existsPassage(String aclSiteId, String passageId);
}
Listato 5.9: definizione MaintenanceFacade
public interface CoreFacade {
Set<PathResponse> findPaths(String aclSiteId, String startRoomId,
String destinationRoomId);
Set<CredentialType> credentialsForPath(String aclSiteId, List<String>
41
passageIdsInPath);
Set<CoreSiteResponse> fetchSites();
CreateGrantResponse createGrant(String aclSiteId, String aclUserId,
List<String> pathIdAsPassageIds, Date from, Date to);
CoreSiteResponse fetchAclSite(String aclSiteId);
UserDesiredState computeUserDesiredState(String aclUserId);
UserDesiredState computeUserDesiredState(String aclSiteId, String
aclUserId);
void revokeAccess(String aclSiteId, String grantId);
void alignAllGrants(String aclSiteId);
boolean canUnlockPathLazy(String aclSiteId, String aclUserId,
List<String> pathAsPassageIds);
boolean canUnlockPathEager(String aclSiteId, String userId,
List<String> passageIdsInPath);
boolean canUnlockPassageEager(String aclSiteId, String aclUserId,
String passageId);
boolean isGrantValid(String grantId);
DesiredState computeDesiredState();
Set<CredentialType> credentialsTypesForPath(String aclSiteId,
List<String> pathAsPassageIds);
Set<Credential> loadUserCredentials(String aclUserId);
CoreGraphResponse fetchGraphByAclSiteId(String aclSiteId);
Set<GrantResponse> fetchGrants(String aclSiteId);
CoreSiteInformationResponse fetchAclSiteInformation(String aclSiteId);
}
Listato 5.10: Definizione CoreFacade
42
5.1.7 Gestione delle eccezioni
Nonostante Java definisca fondamentalmente tutte le tipologie di eccezione
che si possono verificare durante l’esecuzione del codice, sono state create
delle classi per meglio specificare l’eccezione riscontrata.
Tutte le classi create estendono la classe RuntimeException, in modo da
non vincolare lo sviluppatore a gestire tali eccezioni esplicitamente. Infatti, se
le classi estendessero la classe Exception, sarebbe stato necessario inserire
dei blocchi try-catch all’interno del codice oppure aggiungere la clausola
throws alla firma dei metodi, rendendo il codice estremamente verboso e
meno leggibile.
Tali eccezioni sono state inserite nel package net.opfa.exceptions e
sono
• AclSiteNotFoundException
• AclUserNotFoundException
• GrantNotFoundException
• PassageHardwareNotFoundException
• PassageNotFoundException
• RoomNotFoundException
• AccessGroupNotFoundException
• VendorLockNotFoundException
• VendorSiteNotFoundException
• VendorUserNotFoundException
Il modo con cui queste classi sono state scritte è comune: ognuna di esse
infatti definisce due costruttori, uno vuoto e uno che prende come input una
stringa. Il primo serve a impostare un messaggio di default predefinito, il
secondo invece consente di specificarlo. Nel listato 5.11 è stata riportata a
titolo di esempio la classe GrantNotFoundException.
43
public class GrantNotFoundException extends RuntimeException{
public GrantNotFoundException() {
super("Grant not found");
}
public GrantNotFoundException(String message) {
super(message);
}
}
Listato 5.11: la classe GrantNotFoundException
5.1.8 Test
Per testare l’applicazione sono stati scritti diversi test, inseriti nella directory
di default prevista da Maven. Ad eccezione della classe RealScenarioTest,
tutti i test sono di tipo unitario, ovvero testano un singolo componente
software. I moduli testati sono SaltoConnector, SaltoDriver, HalApi,
MaintenanceFacade e CoreFacade.
Il framework impiegato per l’esecuzione dei test è JUnit, nella sua versione
4.13 [16].
5.2 Front end
Il front end si articola in due single page applications, una dedicata al back
office e una dedicata al front office. Si è utilizzato come framework Vue.js
nella sua versione 2.6.14, mentre come linguaggio di programmazione si è
impiegato Javascript 2015, anche noto come ECMAScript 6 [8].
Per navigare all’interno della stessa pagina si è utilizzato Vue Router,
ovvero l’official router del framework [26].
Il frontend interagisce con il back end tramite chiamate REST, che sono
state realizzate con Axios, un client HTTP basato sulle javascript promises
[4]. Nel listato 5.12 è riportato un esempio tipico di una chiamata axios.
axios
.get(‘${process.env.BACKEND_URL}/sites/${process.env.ACLSITE_ID}/graph‘)
.then(response => this.graph = response.data)
44
.catch(error => console.error(error));
Listato 5.12: chiamata axios per ricevere il grafo di un edificio
5.2.1 Comunicazione ad eventi tra i componenti
Qualora un componente di vue ne contenga altri che devono comunicare tra
loro, la comunicazione è stata gestita per mezzo di eventi. L’evento generato
da un componente viene catturato dal componente che lo contiene, per essere
indirizzato al componente interessato.
Questo è il caso ad esempio del tab relativo alla creazione di un grant,
dove una volta selezionato il percorso all’interno del form lo si deve mostrare
colorando le stanze e gli archi interessati, che però sono all’interno di un altro
componente.
5.2.2 Rappresentazione e costruzione del grafo
Per la costruzione e la rappresentazione del cartina si è utilizzato Data-Driven
Documents, o d3.js, una libreria javascript per la manipolazione di documenti
basata sui dati. Tale libreria è molto vasta e consente la rappresentazione di
diversi grafici e non solo. In particolare si è utilizzato il force directed graph
[7] (vedi listato 5.13).
this.simulation = d3
.forceSimulation(rooms)
.force("charge", d3.forceManyBody().strength(-1000))
.force("link", d3.forceLink(passages)
.distance(200)
.id(passage => passage.id))
.force("x", d3.forceX())
.force("y", d3.forceY())
.force("center", d3.forceCenter(width / 2, height / 2))
.on("tick", tickFunction)
Listato 5.13: lancio della simulazione di un force directed graph. Utilizzato
per mostrare a schermo il grafo rappresentante la cartina.
45
5.3 Estetica delle pagine web
Per come vengono rappresentate le pagine web si è utilizzato BootstrapVue,
una libreria di componenti basata interamente sul front end framework css
Bootstrap, nella sua versione 4.5 [5]. All’interno dei singoli componenti tutta-
via è possibile trovare del css specifico del componente stesso. Quest’ultimo,
se presente, è individuato dalla sezione
<style scoped> css code </style>
Per differenziare l’interfaccia del back office da quella del front office si sono
utilizzati dei temi diversi, forniti da Bootswatch [6], una collezione di temi
open source per Bootstrap. Per il front office si è utilizzato il tema zephyr,
mentre per il back office il tema sandstone.
5.4 Sistema di controllo di versione
Si è utilizzato come sistema di controllo di versione git, un version control
system gratuito e open source [10]. La locazione di tutto il codice sviluppa-
to risiede nella repository ”building-access-control”, proprietà dell’account
GitHub aziendale, all’indirizzo
https://github.com/optionfactory/building-access-control
la repository tuttavia è privata, per cui non è visibile.
All’interno della repository sono presenti tre progetti: i due progetti vue
per il front office e il progetto maven del back office.
5.5 Validazione del software
Per verificare la correttezza del software nella sua interezza è stato scritto
un test di sistema, che cerca il più possibile di testare il software nella sua
interezza.
Il test prende il nome di RealScenarioTest, e comincia con la costru-
zione del sito e delle sue stanze e passaggi, aggiungendo su alcuni di essi
dei lucchetti. Il test prosegue con l’assegnazione di un grant ad un utente,
l’applicazione dello stato desiderato seguito dalla revoca del grant appena
assegnato.
46
public class RealScenarioTest {
private MaintenanceFacade maintenanceFacade;
private AclSitesRepository aclSitesRepository;
private CoreFacade coreFacade;
private AclUsersRepository aclUsersRepository;
private GrantsRepository grantsRepository;
private PassageHardwareRepository passageHardwareRepository;
private HalApi halApi;
@Before
public void setup() {
// creazione delle dipendenze
aclSitesRepository = new InMemoryAclSiteRepository();
grantsRepository = new InMemoryGrantsRepository();
aclUsersRepository = new InMemoryAclUserRepository();
passageHardwareRepository = new PassageHardwareRepository
.InMemoryPassageHardwareRepository();
halApi = new HalApi(
passageHardwareRepository,
new FakeSaltoConnector());
maintenanceFacade = new DefaultMaintenanceFacade(
aclSitesRepository,
halApi);
coreFacade = new DefaultCoreFacade(
aclSitesRepository,
aclUsersRepository,
grantsRepository,
halApi);
}
@Test
public void testScenario() {
// Parte manutenzione
47
// creazione del sito
final String aclSiteId = maintenanceFacade
.createAclSite("Option Factory", "Via Beccaria, 6")
.getAclSiteId();
final AclSite aclSite = aclSitesRepository
.findAclSiteById(aclSiteId)
.orElseThrow(AclSiteNotFoundException::new);
Assert.assertNotNull(aclSite);
// creazione delle stanze
final Room outsideRoom = aclSite.getOutside();
final String outsideId = outsideRoom.getId();
final String hallId = maintenanceFacade
.createRoom(aclSiteId, "hall").getRoomId();
// ... segue la creazione delle altre stanze
Assert.assertTrue(maintenanceFacade
.existsRoom(aclSiteId, outsideId));
Assert.assertTrue(maintenanceFacade
.existsRoom(aclSiteId, hallId));
// ... seguono gli altri assert per le altre stanze create
// Creazione dei passaggi
final String outsideHallId = maintenanceFacade
.createPassage(aclSiteId, outsideId, hallId)
.getId();
// ... segue la creazione degli altri passaggi
Assert.assertTrue(maintenanceFacade
.existsPassage(aclSiteId, outsideHallId));
// ... seguono gli altri assert degli altri passaggi
// ricerca di un vendor site
final HalSiteDto halSiteDtoSalto = maintenanceFacade
.fetchHalSitesNotAssigned()
.stream()
.filter(halSite -> halSite
.getCustomerReference()
.equals("Option Factory - SALTO"))
.findFirst()
48
.orElseThrow(VendorSiteNotFound::new);
Assert.assertTrue(maintenanceFacade
.addVendorSiteToAclSite(
aclSiteId,
halSiteDtoSalto.getVendorSiteId(),
halSiteDtoSalto.getVendor(),
halSiteDtoSalto.getCustomerReference()
));
// registrazione dei locks
final String vendorLock1Id = maintenanceFacade
.fetchAllVendorLocks(aclSiteId)
.stream()
.filter(lockResponse -> lockResponse
.getDescription()
.equals("activation code 1"))
.findFirst()
.orElseThrow(VendorLockNotFoundException::new)
.getId();
final String vendorLock2Id = maintenanceFacade
.fetchAllVendorLocks(aclSiteId)
.stream()
.filter(lockResponse -> lockResponse
.getDescription()
.equals("activation code 2"))
.findFirst()
.orElseThrow(VendorLockNotFoundException::new)
.getId();
final String vendorLock3Id = maintenanceFacade
.fetchAllVendorLocks(aclSiteId)
.stream()
.filter(lockResponse -> lockResponse
.getDescription()
.equals("activation code 3"))
.findFirst()
.orElseThrow(VendorLockNotFoundException::new)
.getId();
final String vendorLock4Id = maintenanceFacade
.fetchAllVendorLocks(aclSiteId)
49
.stream()
.filter(lockResponse -> lockResponse
.getDescription()
.equals("activation code 4"))
.findFirst()
.orElseThrow(VendorLockNotFoundException::new)
.getId();
maintenanceFacade.registerLock(
aclSiteId,
office1Hallway1Id,
Vendor.SALTO,
vendorLock1Id);
// ... segue la registrazione degli altri vendor locks
Assert.assertFalse(aclSite.getPassage(hallHallWay1Id)
.orElseThrow(PassageNotFoundException::new)
.getPassageHardwareId().isPresent());
// ... analogamente seguono le altre asserzioni
Assert.assertTrue(halApi.isLockRegistered(
aclSite.getHalSiteIds(),
vendorLock1Id));
// ... analogamente seguono le altre asserzioni
final List<String> allPassagesIds = aclSite
.getAllPassages()
.stream()
.map(Passage::getId)
.collect(Collectors.toList());
Assert.assertTrue(coreFacade
.credentialsTypesForPath(aclSiteId, allPassagesIds)
.contains(CredentialType.PIN));
Assert.assertFalse(coreFacade
.credentialsTypesForPath(aclSiteId, allPassagesIds)
.contains(CredentialType.BLE));
Assert.assertFalse(coreFacade
.credentialsTypesForPath(aclSiteId, allPassagesIds)
.contains(CredentialType.NFC));
Assert.assertFalse(coreFacade
50
.credentialsTypesForPath(aclSiteId, allPassagesIds)
.contains(CredentialType.RFID));
// parte core
final String externalUserId = UUID.randomUUID().toString();
// Ricerca di tutti i passaggi dall’outside alla meeting room
final Set<List<String>> allForwardPathsAsPassageIds = coreFacade
.findPaths(aclSiteId, outsideId, meetingRoomId)
.stream()
.map(PathResponse::getPathAsPassageIds)
.collect(Collectors.toSet());
Assert.assertEquals(2, allForwardPathsAsPassageIds.size());
final List<String> selectedForwardPathAsPassageIds =
allForwardPathsAsPassageIds
.stream()
.filter(forwardPathAsPassageIds -> forwardPathAsPassageIds
.contains(hallway2MeetingRoomAId))
.findFirst()
.orElseThrow(() ->
new IllegalStateException("No forward path found"));
final Set<List<String>> allBackwardPathsAsPassageIds = coreFacade
.findPaths(aclSiteId, meetingRoomId, outsideId)
.stream()
.map(PathResponse::getPathAsPassageIds)
.collect(Collectors.toSet());
final List<String> selectedBackwardPathAsPassageIds =
allBackwardPathsAsPassageIds.stream()
.findFirst()
.orElseThrow(() ->
new IllegalStateException("No backward path found"));
final List<String> selectedCompletePathAsPassageIds = Stream
.concat(selectedForwardPathAsPassageIds.stream(),
selectedBackwardPathAsPassageIds.stream())
.collect(Collectors.toList());
final List<String> passageHardwareIdsOfCompletePath =
selectedCompletePathAsPassageIds
.stream()
51
.map(aclSite::getPassage)
.map(passage -> passage
.orElseThrow(PassageHardwareNotFoundException::new))
.map(Passage::getPassageHardwareId)
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toList());
// assegnazione di un grant valido per una settimana
final Date startDate = new Date();
final long oneWeekInMilliseconds = 1000 * 60 * 60 * 24 * 7;
final Date endDate = new Date(
System.currentTimeMillis() + oneWeekInMilliseconds);
final CreateGrantResponse createGrantResponse = coreFacade
.createGrant(
aclSiteId,
externalUserId,
selectedCompletePathAsPassageIds,
startDate,
endDate);
Assert.assertTrue(coreFacade
.isGrantValid(createGrantResponse.getId()));
final UserDesiredState userDesiredState = coreFacade
.computeUserDesiredState(aclSiteId, externalUserId);
Assert.assertEquals(
userDesiredState.getPassageHardwareIds(),
new HashSet<>(passageHardwareIdsOfCompletePath));
Assert.assertTrue(coreFacade
.canUnlockPathLazy(
aclSiteId,
externalUserId,
selectedForwardPathAsPassageIds));
Assert.assertTrue(coreFacade.canUnlockPathEager(
aclSiteId,
externalUserId,
selectedForwardPathAsPassageIds));
final Set<CredentialType> userCredentialsTypes = coreFacade
.loadUserCredentials(externalUserId)
52
.stream()
.map(Credential::getType)
.collect(Collectors.toSet());
Assert.assertTrue(userCredentialsTypes
.contains(CredentialType.PIN));
Assert.assertFalse(userCredentialsTypes
.contains(CredentialType.BLE));
Assert.assertFalse(userCredentialsTypes
.contains(CredentialType.NFC));
// revoca del grant: lo user desired state deve essere vuoto
coreFacade.revokeAccess(aclSiteId, createGrantResponse.getId());
Assert.assertTrue(coreFacade
.computeUserDesiredState(aclSiteId, externalUserId)
.isEmpty());
}
}
Listato 5.14: codice di RealScenarioTest
53
Capitolo 6
Conclusioni
Gli obiettivi prefissati sono stati raggiunti solo parzialmente. Il progetto
purtroppo si è rivelato molto più complicato del previsto, per cui non tutti i
punti individuati sono stati raggiunti. Molte parti del software infatti sono
solamente simulate, come l’interazione con le piattaforme dei vendors. Inol-
tre, dei vari vendors studiati, è stato scritto soltanto un driver, ovvero quello
del vendor SALTO KS [23].
Complessivamente si è soddisfatti del lavoro svolto, in quanto si è riuscito a
esplorare il problema nella sua complessità e nella sua eterogeneità. Questo
ha portato alla realizzazione di un software che, sebbene incompleto, fornisce
una corretta astrazione del problema. Qualora si volesse dare quindi conti-
nuità al progetto, il software scritto costituisce un valido punto di riferimento
da cui partire.
La realizzazione della demo consente di dare un’idea sufficiente di quello
che, se realizzato, sarà il progetto finale. Molte delle funzionalità mostrate
non sono state implementate, essenzialmente per motivi di tempo, come ad
esempio la possibilità di rimuovere i passaggi e di aggiungere metadati alle
stanze.
Avendo sviluppato il software alla Option Factory S.r.l. ho avuto modo di
conoscere una realtà aziendale, profondamente diversa da quella universita-
ria. Questo mi ha dato la possibilità di capire quale sia l’ambiente lavorativo
al quale sono interessato ma soprattutto il settore lavorativo in cui c’è la
volontà di inserirsi.
54
Nei tre mesi di tirocinio ho avuto modo di ampliare molto le mie conoscen-
ze e di mettere in pratica quelle apprese all’università, apprendendo nuove
tecnologie e affrontando di volta in volta le varie problematiche che si presen-
tavano, da quelle prettamente tecniche alle scelte progettuali. Mansioni come
la consultazione della documentazione del software e la scrittura del codice
hanno avuto infine un impatto importante per la mia crescita personale e in
futuro professionale.
55
Bibliografia
[1] Apache Maven. url: https://maven.apache.org/. visitato il giorno:
21.01.2022.
[2] Apache Tomcat. url: https : / / tomcat . apache . org/. visitato il
giorno: 21.01.2022.
[3] APlus. url: https://www.aplus.srl/. visitato il giorno: 21.01.2022.
[4] Axios. url: https://axios-http.com/. visitato il giorno: 21.01.2022.
[5] Bootstrap 4.5 documentation. url: https : / / getbootstrap . com /
docs / 4 . 5 / getting - started / introduction/. visitato il giorno:
21.01.2022.
[6] Bootswatch. url: https://bootswatch.com/. visitato il giorno: 21.01.2022.
[7] Mike Bostok. Force-Directed-Graph. url: https://observablehq.
com/@d3/force-directed-graph. visitato il giorno: 21.01.2022.
[8] ECMAScript 6. url: https://www.w3schools.com/js/js_es6.asp.
visitato il giorno: 21.01.2022.
[9] Facade Design Pattern. url: https://refactoring.guru/design-
patterns/facade. visitato il giorno: 21.01.2022.
[10] Git. url: https://git-scm.com/. visitato il giorno: 21.01.2022.
[11] Hibernate Site. url: https://hibernate.org/. visitato il giorno:
21.01.2022.
[12] IntelliJ IDEA. url: https://www.jetbrains.com/idea/. visitato il
giorno: 21.01.2022.
[13] JavaScript. url: https://www.javascript.com/. visitato il giorno:
21.01.2022.
[14] JGraphT. url: https://jgrapht.org/. visitato il giorno: 21.01.2022.
56
[15] JSON. url: https://www.json.org/json-en.html. visitato il giorno:
21.01.2022.
[16] JUnit. url: https://junit.org/junit5/docs/current/user-
guide/. visitato il giorno: 21.01.2022.
[17] Manifesto per lo sviluppo agile del software. url: https://agilemanifesto.
org/iso/it/manifesto.html. visitato il giorno: 21.01.2022.
[18] OpenPath. url: https : / / www . openpath . com/. visitato il giorno:
21.01.2022.
[19] Option Factory. url: https://www.optionfactory.net/. visitato il
giorno: 21.01.2022.
[20] Owler. url: https://corp.owler.com/. visitato il giorno: 21.01.2022.
[21] PostgreSQL. url: https://www.postgresql.org/. visitato il giorno:
21.01.2022.
[22] REST APIs. url: https://www.redhat.com/it/topics/api/what-
is-a-rest-api. visitato il giorno: 21.01.2022.
[23] Salto KS. url: https://saltoks.com/. visitato il giorno: 21.01.2022.
[24] Spring Framework. url: https://spring.io/projects/spring-
framework. visitato il giorno: 21.01.2022.
[25] Visual Studio Code. url: https://code.visualstudio.com/. visitato
il giorno: 21.01.2022.
[26] Vue Router Documentation. url: https : / / router . vuejs . org/.
visitato il giorno: 21.01.2022.
[27] Vue.js. url: https://vuejs.org/. visitato il giorno: 21.01.2022.
57

More Related Content

Similar to Prototipazione di una piattaforma di controllo degli accessi fisici cross vendors

Generazione automatica diagrammi di rete con template pptx
Generazione automatica diagrammi di rete con template pptxGenerazione automatica diagrammi di rete con template pptx
Generazione automatica diagrammi di rete con template pptxGiacomoZorzin
 
Analisi e realizzazione di uno strumento per la verifica di conformità su sis...
Analisi e realizzazione di uno strumento per la verifica di conformità su sis...Analisi e realizzazione di uno strumento per la verifica di conformità su sis...
Analisi e realizzazione di uno strumento per la verifica di conformità su sis...Davide Bravin
 
Progettazione e sviluppo di un software applicativo su un single board computer
Progettazione e sviluppo di un software applicativo su un single board computerProgettazione e sviluppo di un software applicativo su un single board computer
Progettazione e sviluppo di un software applicativo su un single board computerAlessandro Mascherin
 
Progetto e sviluppo di un'applicazionemobile multipiattaforma per il supporto...
Progetto e sviluppo di un'applicazionemobile multipiattaforma per il supporto...Progetto e sviluppo di un'applicazionemobile multipiattaforma per il supporto...
Progetto e sviluppo di un'applicazionemobile multipiattaforma per il supporto...maik_o
 
SESAMO (application login automator): evoluzioni applicative e considerazioni...
SESAMO (application login automator): evoluzioni applicative e considerazioni...SESAMO (application login automator): evoluzioni applicative e considerazioni...
SESAMO (application login automator): evoluzioni applicative e considerazioni...AndrijaCiric1
 
Profilazione utente in ambienti virtualizzati
Profilazione utente in ambienti virtualizzatiProfilazione utente in ambienti virtualizzati
Profilazione utente in ambienti virtualizzatiPietro Corona
 
Cloud Computing e Modelli di Business
Cloud Computing e Modelli di Business Cloud Computing e Modelli di Business
Cloud Computing e Modelli di Business Andrea Cavicchini
 
Autenticazione Continua Durante la Navigazione Web Basata sulla Dinamica del ...
Autenticazione Continua Durante la Navigazione Web Basata sulla Dinamica del ...Autenticazione Continua Durante la Navigazione Web Basata sulla Dinamica del ...
Autenticazione Continua Durante la Navigazione Web Basata sulla Dinamica del ...danieledegan
 
Application_level_SLA_monitoring
Application_level_SLA_monitoringApplication_level_SLA_monitoring
Application_level_SLA_monitoringNicola Mezzetti
 
Montalti - "Context aware applications" (2011, master thesys ITA)
Montalti - "Context aware applications" (2011, master thesys ITA)Montalti - "Context aware applications" (2011, master thesys ITA)
Montalti - "Context aware applications" (2011, master thesys ITA)Alessandro Montalti
 
Caratterizzazione dei sistemi cloud per la Pubblica Amministrazione
Caratterizzazione dei sistemi cloud per la Pubblica AmministrazioneCaratterizzazione dei sistemi cloud per la Pubblica Amministrazione
Caratterizzazione dei sistemi cloud per la Pubblica AmministrazioneAmmLibera AL
 
Sviluppo e realizzazione di un sistema per la manipolazione di superfici trid...
Sviluppo e realizzazione di un sistema per la manipolazione di superfici trid...Sviluppo e realizzazione di un sistema per la manipolazione di superfici trid...
Sviluppo e realizzazione di un sistema per la manipolazione di superfici trid...Raffaele Bernardi
 
Tesi Specialistica - L'ottimizzazione delle risorse della Grid di EGEE median...
Tesi Specialistica - L'ottimizzazione delle risorse della Grid di EGEE median...Tesi Specialistica - L'ottimizzazione delle risorse della Grid di EGEE median...
Tesi Specialistica - L'ottimizzazione delle risorse della Grid di EGEE median...Davide Ciambelli
 
Sviluppo di un sistema per il monitoraggio ambientale basato su reti di senso...
Sviluppo di un sistema per il monitoraggio ambientale basato su reti di senso...Sviluppo di un sistema per il monitoraggio ambientale basato su reti di senso...
Sviluppo di un sistema per il monitoraggio ambientale basato su reti di senso...Domenico Schillaci
 
Interfaccia utente basata su eye-tracking per sistemi di controllo ambientale
Interfaccia utente basata su eye-tracking per sistemi di controllo ambientaleInterfaccia utente basata su eye-tracking per sistemi di controllo ambientale
Interfaccia utente basata su eye-tracking per sistemi di controllo ambientaleLuigi De Russis
 
Porting evolutivo dell'applicazione per la gestione dei dispositivi del Comun...
Porting evolutivo dell'applicazione per la gestione dei dispositivi del Comun...Porting evolutivo dell'applicazione per la gestione dei dispositivi del Comun...
Porting evolutivo dell'applicazione per la gestione dei dispositivi del Comun...ozacchig
 
Sistemi SCADA - Supervisory control and data acquisition
Sistemi SCADA - Supervisory control and data acquisitionSistemi SCADA - Supervisory control and data acquisition
Sistemi SCADA - Supervisory control and data acquisitionAmmLibera AL
 
Estrazione automatica di informazioni da documenti cartacei: progetto e reali...
Estrazione automatica di informazioni da documenti cartacei: progetto e reali...Estrazione automatica di informazioni da documenti cartacei: progetto e reali...
Estrazione automatica di informazioni da documenti cartacei: progetto e reali...Luca Bressan
 

Similar to Prototipazione di una piattaforma di controllo degli accessi fisici cross vendors (20)

Generazione automatica diagrammi di rete con template pptx
Generazione automatica diagrammi di rete con template pptxGenerazione automatica diagrammi di rete con template pptx
Generazione automatica diagrammi di rete con template pptx
 
Analisi e realizzazione di uno strumento per la verifica di conformità su sis...
Analisi e realizzazione di uno strumento per la verifica di conformità su sis...Analisi e realizzazione di uno strumento per la verifica di conformità su sis...
Analisi e realizzazione di uno strumento per la verifica di conformità su sis...
 
Progettazione e sviluppo di un software applicativo su un single board computer
Progettazione e sviluppo di un software applicativo su un single board computerProgettazione e sviluppo di un software applicativo su un single board computer
Progettazione e sviluppo di un software applicativo su un single board computer
 
Progetto e sviluppo di un'applicazionemobile multipiattaforma per il supporto...
Progetto e sviluppo di un'applicazionemobile multipiattaforma per il supporto...Progetto e sviluppo di un'applicazionemobile multipiattaforma per il supporto...
Progetto e sviluppo di un'applicazionemobile multipiattaforma per il supporto...
 
SESAMO (application login automator): evoluzioni applicative e considerazioni...
SESAMO (application login automator): evoluzioni applicative e considerazioni...SESAMO (application login automator): evoluzioni applicative e considerazioni...
SESAMO (application login automator): evoluzioni applicative e considerazioni...
 
Profilazione utente in ambienti virtualizzati
Profilazione utente in ambienti virtualizzatiProfilazione utente in ambienti virtualizzati
Profilazione utente in ambienti virtualizzati
 
Cloud Computing e Modelli di Business
Cloud Computing e Modelli di Business Cloud Computing e Modelli di Business
Cloud Computing e Modelli di Business
 
Autenticazione Continua Durante la Navigazione Web Basata sulla Dinamica del ...
Autenticazione Continua Durante la Navigazione Web Basata sulla Dinamica del ...Autenticazione Continua Durante la Navigazione Web Basata sulla Dinamica del ...
Autenticazione Continua Durante la Navigazione Web Basata sulla Dinamica del ...
 
Application_level_SLA_monitoring
Application_level_SLA_monitoringApplication_level_SLA_monitoring
Application_level_SLA_monitoring
 
Montalti - "Context aware applications" (2011, master thesys ITA)
Montalti - "Context aware applications" (2011, master thesys ITA)Montalti - "Context aware applications" (2011, master thesys ITA)
Montalti - "Context aware applications" (2011, master thesys ITA)
 
Caratterizzazione dei sistemi cloud per la Pubblica Amministrazione
Caratterizzazione dei sistemi cloud per la Pubblica AmministrazioneCaratterizzazione dei sistemi cloud per la Pubblica Amministrazione
Caratterizzazione dei sistemi cloud per la Pubblica Amministrazione
 
Sviluppo e realizzazione di un sistema per la manipolazione di superfici trid...
Sviluppo e realizzazione di un sistema per la manipolazione di superfici trid...Sviluppo e realizzazione di un sistema per la manipolazione di superfici trid...
Sviluppo e realizzazione di un sistema per la manipolazione di superfici trid...
 
Tesi Tamiazzo09
Tesi Tamiazzo09Tesi Tamiazzo09
Tesi Tamiazzo09
 
Tesi Specialistica - L'ottimizzazione delle risorse della Grid di EGEE median...
Tesi Specialistica - L'ottimizzazione delle risorse della Grid di EGEE median...Tesi Specialistica - L'ottimizzazione delle risorse della Grid di EGEE median...
Tesi Specialistica - L'ottimizzazione delle risorse della Grid di EGEE median...
 
Sviluppo di un sistema per il monitoraggio ambientale basato su reti di senso...
Sviluppo di un sistema per il monitoraggio ambientale basato su reti di senso...Sviluppo di un sistema per il monitoraggio ambientale basato su reti di senso...
Sviluppo di un sistema per il monitoraggio ambientale basato su reti di senso...
 
Interfaccia utente basata su eye-tracking per sistemi di controllo ambientale
Interfaccia utente basata su eye-tracking per sistemi di controllo ambientaleInterfaccia utente basata su eye-tracking per sistemi di controllo ambientale
Interfaccia utente basata su eye-tracking per sistemi di controllo ambientale
 
Rilevamento intrusioni in wlan
Rilevamento intrusioni in wlanRilevamento intrusioni in wlan
Rilevamento intrusioni in wlan
 
Porting evolutivo dell'applicazione per la gestione dei dispositivi del Comun...
Porting evolutivo dell'applicazione per la gestione dei dispositivi del Comun...Porting evolutivo dell'applicazione per la gestione dei dispositivi del Comun...
Porting evolutivo dell'applicazione per la gestione dei dispositivi del Comun...
 
Sistemi SCADA - Supervisory control and data acquisition
Sistemi SCADA - Supervisory control and data acquisitionSistemi SCADA - Supervisory control and data acquisition
Sistemi SCADA - Supervisory control and data acquisition
 
Estrazione automatica di informazioni da documenti cartacei: progetto e reali...
Estrazione automatica di informazioni da documenti cartacei: progetto e reali...Estrazione automatica di informazioni da documenti cartacei: progetto e reali...
Estrazione automatica di informazioni da documenti cartacei: progetto e reali...
 

Prototipazione di una piattaforma di controllo degli accessi fisici cross vendors

  • 1. UNIVERSITÀ DEGLI STUDI DI TRIESTE Dipartimento di Ingegneria e Architettura Corso di Studi in Ingegneria Elettronica e Informatica PROTOTIPAZIONE DI UNA PIATTAFORMA DI CONTROLLO DEGLI ACCESSI FISICI CROSS-VENDORS Tesi di Laurea Magistrale Laureando: Massimo PALMISANO Relatore: prof. Andrea DE LORENZO Correlatore: Francesco DEGRASSI ANNO ACCADEMICO 2020-2021
  • 2. Indice 1 Introduzione 4 2 Analisi 6 2.1 Scenario . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 2.2 Descrizione del problema . . . . . . . . . . . . . . . . . . . . . 7 2.3 Vendors di riferimento . . . . . . . . . . . . . . . . . . . . . . 8 2.4 Tipologia lucchetti . . . . . . . . . . . . . . . . . . . . . . . . 9 2.5 Tipologia credenziali . . . . . . . . . . . . . . . . . . . . . . . 9 2.6 Vendor site . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 2.7 Definizione requisiti software . . . . . . . . . . . . . . . . . . . 11 3 Progettazione 12 3.1 Modello . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 3.2 Gestione dei diritti utente sui lucchetti . . . . . . . . . . . . . 14 3.3 Modellazione della piantina dell’edificio . . . . . . . . . . . . . 15 3.4 Separation of concerns . . . . . . . . . . . . . . . . . . . . . . 16 3.5 Access Control Logic . . . . . . . . . . . . . . . . . . . . . . . 17 3.6 Hardware Abstraction Layer . . . . . . . . . . . . . . . . . . . 17 3.7 Relazione tra site e vendor site . . . . . . . . . . . . . . . . . . 19 3.8 Limitazioni . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 4 Interfaccia 21 4.1 Installazione e configurazione . . . . . . . . . . . . . . . . . . 21 4.2 Front office . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 4.3 Back office . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 5 Implementazione 26 5.1 Back end . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 1
  • 3. 5.1.1 Strutturazione dei packages . . . . . . . . . . . . . . . 27 5.1.2 Entità principali del modulo HAL . . . . . . . . . . . . 28 5.1.3 Entità principali del modulo ACL . . . . . . . . . . . . 32 5.1.4 Strutturazione del progetto . . . . . . . . . . . . . . . 36 5.1.5 Interazione tra i moduli ACL e HAL . . . . . . . . . . 40 5.1.6 MaintenanceFacade e CoreFacade . . . . . . . . . . . . 40 5.1.7 Gestione delle eccezioni . . . . . . . . . . . . . . . . . . 43 5.1.8 Test . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 5.2 Front end . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 5.2.1 Comunicazione ad eventi tra i componenti . . . . . . . 45 5.2.2 Rappresentazione e costruzione del grafo . . . . . . . . 45 5.3 Estetica delle pagine web . . . . . . . . . . . . . . . . . . . . . 46 5.4 Sistema di controllo di versione . . . . . . . . . . . . . . . . . 46 5.5 Validazione del software . . . . . . . . . . . . . . . . . . . . . 46 6 Conclusioni 54 2
  • 5. Capitolo 1 Introduzione Il controllo dinamico degli accessi ai grandi ambienti, come un grosso edificio aziendale, da sempre costituisce un punto di particolare attenzione per le or- ganizzazioni che li detengono. Questo perché le organizzazioni, come possono essere le aziende, hanno la necessità di gestire gli spazi interni e limitare gli accessi alle proprie aree riservate. L’attuazione di tale controllo è stata per molto tempo difficoltosa, in quanto gli unici dispositivi a disposizione erano le chiavi e le serrature mec- caniche tradizionali, le quali male si prestano a molte delle operazioni deside- rate come la revoca dei permessi o l’accesso a sole determinate fasce orarie ad una particolare area. I dispositivi che invece bene si prestano a questo com- pito sono gli smart locks, o lucchetti intelligenti. I vendors di tali dispositivi sono molti all’interno del mercato, ognuno dei quali presenta ai clienti le pro- prie soluzioni, non prive però di alcune controindicazioni quali, ad esempio, l’impossibilità, di fatto, di avere smart locks diversi all’interno del medesimo edificio e l’obbligo da parte delle organizzazioni a condividere con il vendor molte delle proprie informazioni interne, come quelle relative ai propri utenti. La presente tesi prova a dare una risposta ad entrambe le problematiche. Nello specifico, l’oggetto della tesi è un prototipo di una piattaforma di controllo e di gestione degli accessi fisici di un edificio, all’interno del quale possono essere installati degli smart locks. Il lavoro di tesi ha portato alla produzione di un software, in particolare una applicazione web monolitica con la quale si può interagire tramite interfacce grafiche. Gli obiettivi principali che la piattaforma si propone di raggiungere sono quindi quello di essere cross-vendors - ovvero di garantire la possibilità di avere all’interno dello stesso edificio smart locks di vendors differenti - e di 4
  • 6. sollevare le organizzazioni dall’obbligo di condividere le proprie informazioni interne non necessarie per le meccaniche di controllo degli accessi. Inoltre, si vuole che la piattaforma esponga le seguenti funzionalità: • modellazione degli edifici, definendo le stanze e come sono tra loro collegate • enumerazione dei percorsi percorribili da un utente, filtrando i risultati in base a dei criteri predefiniti • gestione degli utenti e delle credenziali ad essi assegnate Il progetto è stato proposto dall’azienda di sviluppo software OptionFactory S.r.l. [19], dove si è svolto sia il lavoro di tesi che il tirocinio. L’idea del progetto è nata da un dialogo con un cliente, che ha mostrato interesse alla sua realizzazione. Non nascendo da un progetto preesistente, il prototipo è stato progettato dal principio: pertanto, salvo diversa indicazione, tutto il codice cui si fa riferimento è stato scritto dal tesista. Il codice si articola nel suo front end e nel suo back end, che comprende una sezione relativa alla persistenza dei dati. Per lo sviluppo del codice front end si è utilizzato il linguaggio di programmazione JavaScript [13] e il framework Vue.js [27], mentre per il back end si è utilizzato il linguaggio di programmazione Java e il framework Spring MVC [24]. Per la persistenza dei dati si è utilizzato il DBMS relazionale PostgreSQL [21] e Hibernate come ORM - Object Relational Mapping [11]. Infine, si è utilizzato IntelliJ IDEA [12] per la scrittura del codice back end e Visual Studio Code [25] per la scrittura del codice front end. 5
  • 7. Capitolo 2 Analisi Nel presente capitolo si descrivono i passi svolti nell’analisi del problema, partendo dalla raccolta delle informazioni dello scenario di riferimento fino alla definizione dei requisiti e delle funzionalità del software. 2.1 Scenario La gestione dinamica del controllo degli accessi alle aree interne di un edificio, specialmente in ambito aziendale, costituisce da sempre una forte esigenza. Come è facile intuire, i tradizionali lucchetti e serrature meccaniche rendono estramemente complesso l’adempimento di tale esigenza: si pensi, ad esem- pio, alla necessità di elaborare uno storico degli accessi ad un’area riservata o alla necessità di limitare l’accesso di un utente ad una stanza a predefinite fasce orarie. I lucchetti tradizionali quindi male si prestano alla gestione dinamica del controllo degli accessi. Trovano invece forte impiego in questo scenario gli smart locks, ovvero dei lucchetti a funzionamento elettromeccanico che possono essere bloccati o sbloccati presentando loro una credenziale, cioè un dispositivo autorizzato. Generalmente, lo sblocco avviene soltanto dopo un’interazione tra il lucchetto e la piattaforma del vendor, che ha effettuato l’autenticazione dell’utente che ha presentato la credenziale. Le credenziali possono avere forme e dimensioni molto diverse tra di loro: sono infatti esempi di credenziali sono i badge, le carte ma anche gli smart- phone. La comunicazione tra la credenziale e il lucchetto è cifrata, e avviene 6
  • 8. in modalità wireless. Rispetto ai tradizionali lucchetti meccanici, gli smart locks consentono la realizzazione di diverse funzionalità, quali • autorizzazione e autenticazione utente • gestione delle aree in fasce orarie • la revoca, o l’assegnazione, del diritto di un utente di poter bloccare, o sbloccare, un lucchetto da remoto • raccolta degli accessi Gli smart locks generalmente sostituiscono le classiche serrature a maniglia, ma il loro impiego è generale e si possono installare anche su tornelli e cancelli. Inoltre, possono essere applicati su serrature preesistenti. In questo settore di mercato si inseriscono molti vendors, che non si limitano a vendere il singolo smart lock con la chiave ad esso associata, ma forniscono piuttosto un vero e proprio ecosistema. Esso è molto completo ed espone molte funzionalità, come la gestione degli utenti e la modellazione degli spazi. Inoltre, spesso i vendors si occupano anche dell’installazione fisica dei singoli lucchetti. 2.2 Descrizione del problema La scelta da parte di una organizzazione di adottare la soluzione di un vendor non è tuttavia priva di controindicazioni, per cui il rapporto costi- benefici deve essere valutato attentamente. Sono state analizzate le due controindicazioni individuate come principali, cui si è cercato di dare una risposta. La prima è che le soluzioni proposte dai vendors presuppongono la condi- visione dei dati interni dell’organizzazione con la loro piattaforma, portando quindi ad un forte accoppiamento. Quest’ultimo è generalmente fortemen- te indesiderato, in quanto pur non essendo strettamente necessario obbliga l’organizzazione a condividere informazioni interne che prerirebbe mantenere riservate. La seconda importante controindicazione è che le soluzioni proposte dai vendors sono non solo verticali ma anche di tipo vendor lock-in, rendendendo quindi di fatto impraticabile qualsiasi integrazione o coesistenza di soluzioni 7
  • 9. di vendors diversi. Questo si traduce, ad esempio, nell’impossibilità di avere lucchetti di vendors differenti all’interno del medesimo edificio. Non solo, qualora si volesse sostituire la soluzione di un vendor con un’altra, questa operazione è molto complicata e può avvenire solo ad un costo talmente alto da portare l’organizzazione alla rinuncia di tale progetto. 2.3 Vendors di riferimento Uno degli requisiti principali della piattaforma che ci si è proposti di realizzare è la sua capacità di operare su lucchetti di vendors differenti. Questo com- porta il disegno di una astrazione uniforme che sia in grado di rappresentare un generico lucchetto, indipendentemente dal vendor che lo ha fabbricato. Lo stesso vale per come sono state realizzate le implementazioni relative agli utenti e ai loro diritti sui vari lucchetti. Per determinare tali astrazioni è stato perciò necessario la formulazione di un modello che fosse in grado di rappresentare tutti i modelli dei vari vendors, garantendo l’interoperabilità e l’apertura all’integrazione. Altrettanto importante è che tale modello sia sufficientemente generale da essere in grado di rappresentare i vari casi d’uso di interesse, cercando allo stesso tempo di essere il più semplice possibile. Per la formulazione del modello stato necessario studiare le soluzioni impie- gate dai singoli vendors. Tuttavia, nonostante ci siano molti vendors che operano in questo settore, è stato possibile studiare solo alcune di queste. Questo è dovuto alla decisione, da parte dei vendors stessi, di mantenere tali informazioni riservate. Volendo inoltre focalizzare l’attenzione sui vendors che hanno un peso significativo nel mercato, i vendors principali presi in considerazione sono stati i seguenti tre • Salto KS • OpenPath • A-Plus Il livello di dettaglio con cui si sono approfondite tali soluzioni sono diverse, in base al materiale a disposizione. Si è scelto di studiare la soluzione dell’a- zienda Salto KS [23] in quanto è leader del mercato [20] e perché il modello da loro adottato è completo, senza essere eccessivamente complicato. 8
  • 10. L’azienda OpenPath [18] si è scelta in quanto è quella che presenta una maggiore apertura all’integrazione e la documentazione è facilmente accessi- bile. Il modello è il più generale tra quelli che si ha avuto modo di analizzare, e fornisce il più ricco insieme di funzionalità. Tale modello tuttavia è anche molto complicato e pieno di dettagli. Si è scelta infine l’azienda A-Plus [3] in quanto essendoci stati dei contatti con l’azienda ospitante OptionFactory S.r.l si disponeva della documentazio- ne non reperibile pubblicamente. 2.4 Tipologia lucchetti Sul mercato esistono moltissime tipologie di smart locks, che si differenziano per forma e dimensione. Le più comuni sono tuttavia le seguenti tre (vedi figura 2.1): • lucchetto a cilindro • lucchetto a maniglia • lucchetto a muro Figura 2.1: Tipologie comuni di lucchetti offerti dai vendors. Sono riportati i lucchetti del vendor SALTO KS. 2.5 Tipologia credenziali Come per le tipologie di lucchetti, anche le credenziali sono molte e diverse fra loro. Sono esempi di credenziali i badge e le carte, ma anche gli smartphone, 9
  • 11. i tablet e persino gli smartwatch. In figura 2.2 sono riportate le credenziali principali del vendor Openpath [18], ma le stesse che si ritrovano in molti altri vendors. Figura 2.2: Esempi di credenziali del vendor Openpath. Sono spesso le stesse di altri vendors. Le tecnologie più comuni per l’interazione tra esse e i lucchetti sono le seguenti • PIN - Personal Identification Number • BLE - Bluetooth Low Energy • NFC - Near Field Communication • RFID - Radio Frequency IDentification 2.6 Vendor site Per poter utilizzare i lucchetti e le credenziali di un vendor, è prima necessario associarle all’edificio nel quale verranno impiegate. Tale registrazione avviene 10
  • 12. nella piattaforma del vendor creando un sito, che corrisponde al concetto di edificio (caratterizzato da un nome e da indirizzo postale), e associando ad esso i lucchetti e le credenziali desiderate. Per motivi che saranno chiari in seguito, si utilizzerà l’espressione vendor site in luogo di sito. 2.7 Definizione requisiti software Il software che si intende realizzare quindi è una piattaforma di controllo e di gestione degli accessi fisici, che deve implementare ed esporre le seguenti funzionalità • operare su hardware di vendors differenti, offrendo un set di funzionalità comuni • esporre funzionalità logiche di alto livello, indipendenti dall’integrazio- ne hardware, quali – modellazione degli ambienti e dei varchi che li collegano – enumerazione dei percorsi disponibili, dato l’insieme di ambienti cui un utente deve avere accesso – applicazione di logiche autorizzative, per escludere o limitare i percorsi disponibili sulla base di proprietà di ambienti e di varchi – mappatura di utenti e credenziali • garantire l’allineamento tra il modello astratto e la configurazione in campo, notificando eventuali scostamenti • raccogliere eventi dal campo, utilizzati per il controllo di sicurezza, business intelligence e manutenzione Gli obiettivi proposti sono • evitare il vendor lock-in • separare dati sensibili, aspetti di dominio e identità degli utenti dalle meccaniche di controllo degli accessi • garantire l’apertura per l’integrazione in piattaforme di business 11
  • 13. Capitolo 3 Progettazione In questo capitolo viene trattato come, a partire dall’analisi, si è arrivati alla progettazione del software, indicando di volta in volta le scelti progettuali adottate. 3.1 Modello Il modello proposto ha come obiettivo quello di fornire un’astrazione ca- pace di generalizzare tutti i modelli dei vari vendors, mantenendo la capa- cità di rappresentare tutti i casi d’uso di interesse senza però rinunciare alle funzionalità che si intende esporre. Esso si fonda sui seguenti concetti chiave Site Un sito, o site, rappresenta un edificio fisico caratterizzato da un vero e pro- prio indirizzo postale su cui è possibile l’installazione di lucchetti di vendors diversi. Graph Il grafo, o graph, rappresenta la piantina di un sito, descrivendo le stanze e come sono tra loro collegate. 12
  • 14. Room Una stanza, o room, rappresenta generalmente una stanza (e.g. l’atrio) oppure altri spazi o ambienti, come possono essere il corridoio o le scale. Passage Un passaggio, o passage, è un’unità di accesso fisico che indica la possibilità di accedere da una stanza ad un’altra senza passare per stanze intermedie. Generalmente è una porta, ma può corrispondere ad un cancello o ad un ascensore. Su di esso possono essere installati più dispositivi, che ne gesti- scono il blocco e lo sblocco. Il passaggio è inoltre unidirezionale, per poter modellare situazioni in cui date due stanze è possibile partendo da una acce- dere all’altra ma non viceversa. Si pensi, a titolo di esempio, ad una porta antincendio. Passage Hardware Con passage hardware si intende l’insieme di dispositivi installati su un pas- saggio, che ne gestiscono l’apertura e la chiusura. È sufficiente avere i diritti di sbloccare uno solo di questi per poter percorrere il passaggio. Siccome sul medesimo passaggio è possibile installare soltanto lucchetti di un medesimo vendor, che quindi saranno associati al medesimo vendor site, l’identificativo di un passage hardware è stato costruito concatenando il nome del vendor, il vendor site id dei lucchetti che compongono il passage hardware e un’ulteriore stringa, generata internamente: vendorvendor site idhardware id Lock Un lucchetto, o lock, rappresenta un dispositivo in grado di bloccare o sbloc- care un passaggio. Appartiene ad un solo sito ed è caratterizzato da una particolare modalità di apertura e dal vendor che lo ha fabbricato. Credential Una credenziale, o credential, è qualsiasi dispositivo che un utente può utiliz- zare per sbloccare un passage hardware. Ogni credenziale è caratterizzata da 13
  • 15. un protocollo di comunicazione. Sono stati presi in considerazione i protocolli più comuni quali il PIN, il BLE, l’NFC e l’RFID. User Un utente, o user, è una entità che rappresenta un utente dell’organizzazione, cui possono essere associate una o più credenziali. Access Group Un gruppo di accesso, o access group, determina un insieme di utenti e i lucchetti che possono sbloccare. Grant Un grant è un permesso associato ad un site ed è caratterizzato da un periodo di validità. Definisce quali sono i passaggi che l’utente cui è assegnato ha accesso. 3.2 Gestione dei diritti utente sui lucchetti I diritti di un utente su un lucchetto è determinato dagli access group ai quali appartiene. In particolare, un utente u può aprire un lucchetto l se e solo se appartiene ad almeno un access group ag tale che abbia il diritto di aprire il lucchetto l. Per implementare la gestione del controllo degli accessi quindi bisogna determinare una strategia riguardo la gestione degli access groups. Ne sono state individuate tre: 1. un access group per utente 2. un access group per lucchetto 3. un access group per percorso Per la sua semplicità e flessibilità, la strategia che si è deciso di impiegare è la stretegia numero 2. In questo modo qualora si volesse dare ad un utente u l’accesso ad un lucchetto l è sufficiente aggiungerlo all’access group ag relativo 14
  • 16. a l. Analogamente, qualora si volesse revocare tale diritto, sarebbe sufficien- te rimuovere u da ag. In questo modo inoltre, qualora si volesse sostituire il lucchetto di un passage con un altro (e.g. per un guasto), sarebbe suffi- ciente sostituire il lucchetto dell’access group con quello nuovo. La strategia tuttavia introduce un alto numero di access group: uno per lucchetto. 3.3 Modellazione della piantina dell’edificio Si è deciso di modellare la cartina del building con un grafo bidirezionale, dove ogni nodo è una stanza e ogni arco è un passaggio (vedi figura 3.2). In ogni grafo è sempre presente un nodo denominato outside, che rappresenta il mondo esterno dal quale si accede all’edificio. Si prenda a titolo di esempio la piantina di figura 3.1. Meeting Room Hall Office Bathroom hallway Figura 3.1: Esempio cartina di un edificio Il grafo equivalente è quindi costituito da sei nodi. Quattro di essi rap- presentano le stanze hall, bathroom, meeting room e office, mentre i restanti 15
  • 17. due sono usati per rappresentare l’ambiente esterno e il corridoio hallway. Il grafo che si ottiene a partire dalla cartina di figura 3.1 è rappresentato in figura 3.2. outside hall hallway bathroom meeting room office Figura 3.2: Grafo equivalente della cartina di figura 3.1 3.4 Separation of concerns Per poter realizzare le funzionalità desiderate, il middleware deve comunicare con le piattaforme dei singoli vendors. Tuttavia, questa necessità è ortogonale alla logica di business dell’applicazione. Si è deciso allora di suddividere il middleware in due layers: il primo, che opera a livello logico più alto, si occupa di realizzare la business logic e si appoggia al secondo layer, che opera invece ad un livello logico più basso e si occupa di dialogare con le 16
  • 18. piattaforme dei singoli vendors, fornendo al layer soprastante un’interfaccia uniforme. Definiamo allora Access Control Logic - ACL il layer di più alto livello e Hardware Abstraction Layer - HAL il layer di livello più basso (vedi figura 3.3). Access Control Logic Hardware Abstraction Layer Middleware Figura 3.3: I due layer di cui si compone il middleware: l’Access Control Logic e l’Hardware Abstraction Layer 3.5 Access Control Logic L’Access Control Logic è il modulo che si occupa della logica di business dell’applicazione, esponendone tutte le funzionalità. Gli utenti finali sono due: i manutentori, che si occupano della installazione dei lucchetti e del- la costruzione della cartina dell’edificio, e il personale della reception, che invece si occupa dell’assegnazione delle credenziali e dei diritti agli utenti dell’organizzazione. Per ciascun attore si vuole fornire una interfaccia da cui saranno fruibili le funzionalità di cui ha bisogno. Una è quindi dedicata al back office, la seconda invece è dedicata al front office. Siccome tali interfacce espongono funzionalità in generale diverse pur appoggiandosi allo stesso modulo, si è deciso di seguire il facade design pattern, e quindi scrivere una facade per insieme di funzionalità. Le due facade sono state denominate Core Facade e Maintenance Facade (vedi figura 3.4), che quindi sono parte integrante dell’ACL. 3.6 Hardware Abstraction Layer L’Hardware Abstraction Layer deve fornire all’Access Control Logic una astrazione che sia indipendente dal particolare vendor sottostante, e quindi 17
  • 19. Access Control Logic Maintenance Facade Core Facade Front Office Back Office Figura 3.4: L’Access Control Logic si interfaccia con due facade: la Core Facade e la Maintenance Facade l’interfaccia che espone deve essere uniforme. Per realizzare tale astrazione al suo interno l’HAL si compone di diversi driver, uno per vendor (vedi fi- gura 3.5). Le varie richieste che l’HAL riceverà saranno quindi smistate e indirizzate al driver del vendor opportuno. In questo modo si riesce ad essere aperti all’integrazione: qualora si volesse aggiungere il supporto ai lucchetti di un altro vendor sarà sufficiente implementare il driver corrispondente. Hardware Abstraction Layer Driver Vendor 1 Driver Vendor 2 ... Figura 3.5: L’hardware abstraction layer si appoggia ai driver che si occupano di interagire con la piattaforma del vendor corrispondente 18
  • 20. 3.7 Relazione tra site e vendor site Nel modello, un sito può ospitare al suo interno lucchetti di vendors differenti, che sono associati ad un vendor site (vedi paragrafo ...). Questo significa che un sito è associato a sua volta a tanti vendor sites quanti sono i vendors differenti dei lucchetti che ospita. Sussiste una relazione quindi uno a molti (vedi figura 3.6). Siccome in generale è possibile due vendor site di vendors diversi abbiano lo stesso id, per identificare univocamente un vendor site si è costruita una stringa come segue vendor namevendor site id cui diamo il nome, per motivi che saranno chiari in seguito, hal site id. Infine, per distinguere i siti definiti all’interno dell’ACL da quelli dei vari vendors, denotiamo i primi acl site e i secondi vendor site. acl site vendor site 1 vendor site 2 vendor site 3 Figura 3.6: Un acl site può essere associato a più vendor site 3.8 Limitazioni Alcune operazioni di interesse, come la registrazione di un lock o di una credenziale ad un vendor site, non sono state automatizzate. Questo perché tali operazioni prevedono molti passaggi, alcuni dei quali per loro natura sono di difficile automatizzazione. Non solo, l’automatizzazione di tali procedure è resa complessa a causa della eterogeneità delle procedure previste dalle piattaforme dei vendors. Per questi motivi si è lasciato agli operatori il compito di svolgere manualmente le procedure previste dalle piattaforme dei vari vendors. 19
  • 21. A titolo di esempio, si consideri la procedura prevista dal vendor SALTO KS per l’associazione di un badge ad un suo vendor site. Essa prevede di avvicinare il badge ad un lucchetto posto in modalità registrazione, cui se- guirà un segnale sonoro che indica la corretta associazione della credenziale al medesimo vendor site del lucchetto. Si evince facilmente quindi che tale operazione per sua natura non è automatizzabile. 20
  • 22. Capitolo 4 Interfaccia Come anticipato nei capitoli precedenti, l’interfaccia si compone di due ap- plicazioni web. Una è dedicata al back office, come i manutentori, l’altra al front office, ovvero il personale della reception. 4.1 Installazione e configurazione Per utilizzare il software è necessario avviare l’applicazione web. Il server è configurato per eseguire il binding sulla porta 8080 della macchina locale sulla quale viene avviato. 4.2 Front office Per accedere all’interfaccia del front office, si apra un browser e si navighi all’indirizzo http://hostname :8080/core/site id La pagina web si compone di diversi tabs, di cui il primo è quello mostrato di default e consiste in una pagina di benvenuto (vedi figura 4.1). Questa mostra alcune informazioni generali dell’edificio, come il numero di stanze e di passaggi di cui si compone. Il secondo tab invece consente di gestire i permessi assegnati ai vari utenti dell’organizzazione tramite una tabella, che prende il nome di Grants Table (vedi figura 4.2). Ogni riga di cui si compone corrisponde quindi ad un grant, 21
  • 23. Figura 4.1: pagina di benvenuto del front office in cui vengono mostrate le relative informazioni quali l’utente cui è assegnato, il sito cui fa riferimento, i passaggi che può sbloccare e il periodo di validità dello stesso. Inoltre, nell’ultima cella è presente un bottone che ne consente la revoca. Figura 4.2: tab che mostra una tabella contenente i grants Il terzo tab infine consente di assegnare i grants agli utenti della organizza- zione. Sulla sinistra viene mostrato un form, mentre sulla destra invece viene mostrata la cartina dell’edificio sotto forma di grafo. Per assegnare un nuovo grant è necessario compilare i campi del form, che si articolano in 22
  • 24. • stanza di partenza • stanza di arrivo • percorsi possibili • utente cui assegnare il grant • data inizio validità del grant • data fine validità del grant Una volta indicata la stanza di partenza e di arrivo, vengono mostrati i percorsi possibili che è possibile assegnare elencando le stanze da percorrere. Per rendere più immediato quale siano le stanze di cui è costituito il percorso scelto, i nodi e gli archi che non sono coinvolti assumono una colorazione grigia, in modo da rendere più evidente all’operatore il percorso che sta per assegnare all’utente (vedi figura 4.3). Figura 4.3: Screenshot del tab ”Create Grant” 23
  • 25. 4.3 Back office Per accedere all’applicazione web relativa al back office si navighi all’indirizzo url http://hostname :8080/maintenance/site id Il sito web si compone di due tab. Il secondo è composto di due tabelle: la prima mostra i siti dei vendors attualmente associati al sito, la seconda invece quelli per cui non è presente alcuna associazione e che quindi possono essere associati (vedi figura 4.4). Figura 4.4: Screenshot del tab ”vendor sites” Il primo tab invece, mostrato di default, è relativo alla cartina dell’edificio, dove vengono in particolare mostrati tre form e la mappa della cartina stessa, anche qui sotto forma di grafo (vedi figura 4.5). Gli archi del grafo mostrano, qualora presenti dei lucchetti installati su di essi, le modalità di sblocco per passare il passaggio stesso. Il form ”Add Room” consente di aggiungere una stanza alla piantina, specificando il nome della stessa. È inoltre possibile assegnare alla stanza alcuni attributi, indicati come checkboxes (e.g. se è un’area riservata). La stanza creata costituisce inizialmente un nodo isolato, ma può essere connesso agli altri successivamente. Il form ”Add Passage” invece consente di aggiungere un passaggio speci- ficando la coppia di stanze che connette. Essendo i passaggi monodirezionali, 24
  • 26. l’ordine delle stanze è rilevante. È comune che qualora esista un passaggio tra due stanze, esso sia bidirezionale. Per migliorare l’esperienza utente, contras- segnando il checkbox ”bidirectional” vengono creati direttamente entrambi i passaggi. Infine, il form ”Add Lock” consente di aggiungere un lucchetto ad un passaggio, scegliendo tra i vendor sites associati al sito corrente. Una volta aggiunto, comparirà il vendor del lucchetto nel passaggio indicato. Figura 4.5: Screenshot del tab ”building map” 25
  • 27. Capitolo 5 Implementazione L’implementazione del progetto si articola nella realizzazione del suo back end e del suo front end. Si è sviluppato il progetto seguendo la metodologia agile, i cui principi sono indicati nel suo manifesto [17]. All’interno del capitolo sono presenti alcuni diagrammi di classe UML delle entità che compongono il progetto. Lo scopo di tali diagrammi è quello di rendere la trattazione maggiormente chiara piuttosto che dare una descri- zione dettagliata ed esaustiva delle entità che descrivono. Per questo motivo, alcuni campi o metodi potrebbero essere omessi per meglio mettere in luce quelli di maggiore interesse alla trattazione. Sempre per rendere la trattazione più chiara possibile, all’interno del ca- pitolo sono stati anche riportati alcuni frammenti di codice per la descrizione di metodi e interfacce. All’interno degli stessi alcune parti potrebbero essere omesse, per rendere il codice meno verboso e più significativo ai fini della trattazione. 5.1 Back end Il codice è stato scritto all’interno del framework Spring MVC [24]. Esso si articola in due moduli: l’Access Control Logic e l’Hardware Abstraction Layer, entrambi inseriti nel package net.opfa. La scelta del linguaggio di programmazione per la scrittura di entrambi i moduli è quindi ricaduta su Java, nella sua versione 17. Per eseguire il build del progetto sono necessari diversi steps, come la compilazione del codice sorgente, l’esecuzione dei test automatizzati e del 26
  • 28. packaging dell’applicazione. Per questi tasks si è utilizzato Apache Maven, un software project management e un comprehension tool [1]. Il web server è stato esteso con l’architettura delle Java Servlet, che pre- vede l’impiego di un servlet container, ovvero di un programma specifico che mette a disposizione un ambiente ricco di funzionalità sfruttabili per la scrit- tura di programmi Java per il calcolo dinamico delle pagine, che prendono il nome di servlet. Il servlet container utilizzato è Apache Tomcat, un software open source che implementa alcune specifiche della piattaforma Jakarta EE [2]. La versione utilizzata è la 9.0.56. 5.1.1 Strutturazione dei packages Tutto il codice è all’interno del root package net.opfa. Per la suddivisione dello stesso erano possibili due strategie: la strutturazione per feature, o verticale, che prevede un package per ogni singola feature, e la strutturazione per layer, o orizzontale, che invece prevede tanti livelli di packages quanti sono i livelli in cui è strutturata l’applicazione. Siccome un criterio non è necessariamente migliore dell’altro, si è scelta la strutturazione per layer per comodità. net.opfa acl exceptions common configuration hal controllers core maintenance drivers Figura 5.1: organizzazione dei packages per layer; non esaustiva Il package net.opfa.common contiene tutte le classi comuni all’intera ap- plicazione come la classe Credential o la classe Vendor. Le classi neces- sarie per la corretta configurazione di Spring MVC come la configurazione del DBMS e dei controllers invece sono stati inseriti all’interno del package net.opfa.configuration. Infine, nel package net.opfa.vendors sono sta- te inserite le classi dei vari drivers, sebbene al momento si compone di un solo package, contenente le classi del driver per il vendor SALTO KS [23]. 27
  • 29. 5.1.2 Entità principali del modulo HAL In questa sezione si elencano le entità principali del modulo Hardware Ab- straction Layer, concludendo con la stesura del relativo schema E-R. Passage Hardware Il concetto di passage hardware è implementato dalla classe PassageHardware (vedi figura 5.2). Siccome ad un passage hardware è possibile aggiungere, o togliere, un lucchetto dinamicamente nel tempo, sono previsti dei metodi che adempiano a tali operazioni. Inoltre, i lucchetti che lo compongono determi- nano le modalità di apertura del passage hardware. Infine, siccome a partire dall’id si possono ottenere informazioni utili come il vendor site id, sono stati scritti dei metodi statici per eseguirne il parsing. PassageHardware + String id + Set<CredentialTypes> unlockModes + Set<String> lockIds + addLocks() + removeLocks() + getHalSiteId() + getVendoSiteId() + getVendor() + getHardwareId() Figura 5.2: Diagramma delle classi UML per la classe PassageHardware Lock La classe Lock rappresenta il concetto di lucchetto ed è quindi caratterizzato dal particolare venditore che lo ha fabbricato, la sua modalità di sblocco, il suo identificativo e una descrizione dello stesso, che servirà al manutentore per accertarsi che il lucchetto sta aggiungendo ad un passaggio sia lo stesso che ha installato. 28
  • 30. Ad esempio, nel caso dell’installazione di un lucchetto del vendor SALTO KS, la descrizione di un lock è il suo activation code, una stringa univoca di caratteri sovra impressi fisicamente sul lucchetto. Quindi, quando un manutentore vuole indicare che in un certo passaggio è stato aggiunto quel lucchetto, gli sarà sufficiente selezionare il lucchetto caratterizzato da quel particolare activation code. L’identificativo del lock è una stringa che contiene informazioni relativa- mente al venditore, all’identificativo del sito del venditore cui appartiene e dall’identificativo proprio del lucchetto dato dal venditore. Analogamente all’id della classe PassageHardware, l’id di un lock si è costruito come vendorvendor site idvendor lock id La classe risultante è riportata in figura 5.3 Lock + String id + String description + CredentialType lockType + getVendor() + getVendorSiteId() + getVendorLockId() + buildLockId() Figura 5.3: Diagramma delle classi UML per la classe Lock Desired State Per fare in modo che il modello astratto si concretizzi nel mondo reale, è ne- cessario effettuare le opportune operazioni sulle piattaforme dei vari vendors, di cui si occuperà l’HAL. A tale scopo due approcci sono possibili: l’approccio imperativo, per il quale l’ACL indica all’HAL le singole operazioni in modo puntuale che deve eseguire, oppure l’approccio funzionale, per il quale l’ACL passerà all’HAL lo stato desiderato atteso che quest’ultimo dovrà tradurre nelle corrispondenti operazioni. 29
  • 31. Il concetto di stato atteso è implementato dalla classe DesiredState, che ha al suo interno una mappa che tiene traccia lo stato atteso di ogni utente (vedi figura 5.4) DesiredState + Map<String, UserDesiredState> desiredStateMap + isEmpty() + addUserDesiredState() Figura 5.4: Diagramma delle classi UML per la classe DesiredState Lo stato atteso di ogni utente è implementato dalla classe UserDesiredState, che definisce per ogni utente i passage hardware che deve essere in grado di aprire a partire dalle sue credenziali. UserDesiredState + String aclUserId + Set<String> passageHardwareIds + Set<Credential> userCredentials + isEmpty() Figura 5.5: Diagramma delle classi UML per la classe UserDesiredState Il metodo che si occupa di calcolare lo stato atteso è computeDesiredState() (vedi listato 5.1), che utilizza il metodo computeUserDesiredState() (vedi listato 5.2). @Override public DesiredState computeDesiredState() { final DesiredState desiredState = new DesiredState(); 30
  • 32. final Set<AclUser> aclUsers = aclUsersRepository.findAllUsers(); aclUsers .stream() .map(AclUser::getId) .map(this::computeUserDesiredState) .forEach(desiredState::addUserDesiredState); return desiredState; } Listato 5.1: Metodo che si occupa di calcolare lo stato atteso Il metodo computeUserDesiredState() determina quali sono i passaggi che un utente deve essere in grado di aprire a partire dai grants ad esso associati. @Transactional @Override public UserDesiredState computeUserDesiredState(String aclUserId) { final Set<Grant> grants = grantsRepository.findUserGrants(aclUserId); final AclUser aclUser = aclUsersRepository.findUserById(aclUserId) .orElseThrow(AclUserNotFoundException::new); if (grants.size() == 0) { return new UserDesiredState( aclUserId, new HashSet<>(), aclUser.getCredentials()); } else { final String aclSiteId = grants .stream() .findFirst() .get() .getAclSiteId(); return computeUserDesiredState(aclSiteId, aclUserId); } } Listato 5.2: Metodo che si occupa di calcolare lo stato atteso di ogni utente 31
  • 33. Schema E-R Lo schema E-R del modulo HAL è quindi molto semplice (vedi figura 5.6). Per mantenere il modulo ACL con il modulo HAL il più disaccoppiati pos- sibile, all’interno di quest’ultimo non vi è alcun riferimento ai passaggi cui i passage hardware sono associati. Passage Hardware appartenenza Lock (1,1) (1,N) Figura 5.6: Schema E-R modulo HAL 5.1.3 Entità principali del modulo ACL Come per il modulo HAL, in questa sezione sono descritte le entità principali del modulo ACL, concludendo con la descrizione del relativo schema E-R. Room La classe Room rappresenta il corrispondente concetto di room e costituisce un nodo del grafo. Essa è caratterizzata da un id e da alcuni metadati, come il nome della stanza stessa. Passage La classe Passage rappresenta il corrispondente concetto di passage e costi- tuisce gli archi del grafo. Anch’esso è caratterizzato da un id come la classe Room. Inoltre, se presente, presenta come attributo una stringa che indica qual è il passage hardware id installato. Siccome tale parametro è opzionale, il getter non si limita a restituire la stringa, ma la avvolge in un wrapper java.util.Optional (vedi listato 5.3). public Optional<String> getPassageHardwareId() { return Optional.ofNullable(this.passageHardwareId); } Listato 5.3: getter della classe PassageHardware 32
  • 34. AclSite La classe AclSite rappresenta il corrispondente concetto di site, ed è quindi caratterizzata da un id, un nome, un indirizzo postale e un grafo che ne modella la cartina. Il grafo e le operazioni ad esso associate sono state implementate ricorren- do a JGrapht, una libreria java di strutture dati e algoritmi della teoria dei grafi [14]. La libreria offre molte implementazioni della struttura dati grafo, tante quante le particolari tipologie dello stesso (e.g. grafo diretto aciclico, grafo direzionato, multigrafo). La classe che si adatta al nostro caso d’uso è la classe org.jgrapht.graph.DirectedPseudoGraph, ovvero un’implemen- tazione di un pseudografo direzionato che consente di utilizzare una qualsiasi classe sia per i vertici che per gli archi. I nodi quindi saranno istanze della classe Room, mentre gli archi saranno istanze della classe Passage. Esso può avere uno o più hal site id, che identificano i vendor site cui sono associati. La classe risultante è riportata in figura 5.7. AclSite + String id + String name + String address + Set<String> halSiteIds + addRoom() + addPassage() + removePassage() + removeRoom() + getOutside() + addHalSiteId() + getHalSiteIds() Figura 5.7: Diagramma di classe UML della classe AclSite 33
  • 35. Path Si è deciso di rappresentare il concetto di percorso, o path, come una sequen- za ordinata di passaggi. Non esiste una vera e propria classe Path, in quanto non sarebbe stata altro che un wrapper di List<String> passageIds, ov- vero una sequenza ordinata di stringhe, ognuna delle quali identificante un passaggio del grafo. Non è possibile rappresentare un percorso come sequenza di stanze in quanto in base al nostro modello in generale è possibile passare da una stanza all’altra con passaggi diversi, che possono avere lucchetti di vendors diversi. Nel modello utilizzato pertanto dati due passaggi che han- no la medesima stanza di partenza e di arrivo, un utente potrebbe essere in grado di percorrere uno ma non l’altro. Partendo da una coppia di stanze e dal loro sito di appartenenza il metodo findAllPaths() trova l’insieme di tutti i percorsi possibili (vedi listato 5.4). Per determinarli viene fatto uso della classe AllDirectedPath, una classe del package org.jgrapht.alg.shortestpath definita nella libreria jgrapht. La classe è un algoritmo Dijkstra-like, che determina tutti i percorsi tra due insiemi di nodi in un grafo direzionato, con l’opzione di cercare soltanto i percorsi semplici e limitare la lunghezza del percorso. private Set<List<String>> findAllPaths( AclSite aclSite, Room startRoom, Room destinationRoom) { final AllDirectedPaths<Room, Passage> allPaths = new AllDirectedPaths<>(aclSite.getGraph()); return allPaths .getAllPaths(startRoom, destinationRoom, true, Integer.MAX_VALUE) .stream() .map(path -> path .getEdgeList() .stream() .map(Passage::getId) .collect(Collectors.toList())) .collect(Collectors.toSet()); } Listato 5.4: Metodo per determinare tutti i percorsi possibili (semplici) data una coppia di stanze 34
  • 36. Credential La classe credential rappresenta il corrispondente concetto di credential ed è stato implementato come value type, ovvero un oggetto privo di identifica- tivo. I campi di tale oggetto sono la sua tipologia (e.g. BLE, NFC) e il valore numerico al suo interno, che verrà scansionato dal lucchetto al quale viene presentata. L’oggetto Credential quindi non rappresenta la credenziale di questo o quel vendor. La classe risultante è rappresentata in figura 5.8. Credential + CredentialType credentialType + String value Figura 5.8: Diagramma delle classi UML per la classe Credential AclUser Un AclUser è un placeholder che ha la sola funzione di rappresentare un utente dell’organizzazione, senza però alcuna informazione aggiuntiva. In questo modo si evita che l’organizzazione condivida alcuna informazione in- terna. Le uniche informazioni di un utente acl quindi sono le credenziali che esso possiede (vedi figura 5.9). AclUser + String id + Set<Credential> credentials Figura 5.9: Diagramma delle classi UML per la classe AclUser Schema E-R Lo schema E-R risultante del modulo ACL è riportato in figura 5.10 35
  • 37. Sito generazione Grant (1,1) (1,1) appartenenza (0, N) Utente (1, N) assegnazione (1, 1) (0, N) ownership (0, N) Credential (1, 1) Figura 5.10: Schema E-R del modulo ACL 5.1.4 Strutturazione del progetto L’architettura scelta per la strutturazione di entrambi i moduli è una strut- tura che si articola in diversi layer (vedi figura 5.11). APIs Nel caso del modulo ACL, le sue funzionalità sono esposte tramite dei servizi web, implementati seguendo il pattern dei RESTful Web Services [22]. Per la loro creazione si sono utilizzati gli spring rest controllers, che si occupano di mappare le richieste ai metodi corrispondenti. Il formato scelto dell’oggetto restituito è il formato JSON [15]. Le APIs esposte si possono raggruppare concettualmente in due insiemi: quelle dedicate al front office e quelle dedicate al back office. I primi sono 36
  • 38. APIs Facade Repositories Database Figura 5.11: Architettura progetto mappati all’indirizzo url http://hostname /core/*, i secondi all’indirizzo http://hostname /maintenance/*. Per ciascun insieme sono stati scritti due controllers: il CoreController e il MaintenanceController, entrambi inseriti nel package net.opfa.controllers. @RestController public class MaintenanceController { @Autowired MaintenanceFacade maintenanceFacade; // seguono altri metodi } Listato 5.5: Definizione MaintenanceController Ogni controller ha un metodo che cattura un’eventuale eccezione che si dovesse verificare all’interno del codice: tale metodo è stato denominato catchNotFoundException ed è stato annotato con @ExceptionHandler (ve- di listato 5.6). @ResponseStatus(HttpStatus.NOT_FOUND) @ExceptionHandler(value = { RoomNotFoundException.class, AclUserNotFoundException.class, AclSiteNotFoundException.class, PassageNotFoundException.class, }) public String catchNotFoundException(RuntimeException exception) { 37
  • 39. return exception.getMessage(); } Listato 5.6: Definizione dell’exception handler Il modulo Hardware Abstraction Layer invece essendo interno al progetto espone le APIs come semplici metodi java, che l’Access Control Logic può in- vocare. Tali metodi sono definiti nell’interfaccia HalApi, presente nel package net.opfa.hal (vedi listato 5.7). public interface HalApi { List<Lock> listAllVendorLocks(Set<String> halSiteIds); boolean isLockRegistered(String halSiteId, String lockId); boolean isLockRegistered(Set<String> halSiteIds, String lockId); List<HalSiteDto> fetchHalSites (); Set<CredentialType> findCredentialTypesForPassageHardwareSet( Set<String> passageHardwareIds); Set<CredentialType> findCredentialTypesForPassageHardware( String passageHardwareId); void applyUserDesiredState(UserDesiredState userDesiredState); Set<Credential> loadUserCredentials( String externalUserId, Set<String> halSiteIds); boolean canUnlockPassageHardware( String aclUserId, String passageHardwareId, Set<Credential> userCredentials); String createPassageHardware( Vendor vendor, String vendorSiteId, String lockId); void addLockToPassageHardware( String passageHardwareId, 38
  • 40. Vendor vendor, String lockId); } Listato 5.7: Metodi di HalApi Facade Pattern Si è adottato come design pattern strutturale il facade pattern, che fornisce una interfaccia semplificata ad una libreria, a un framework o a un qualche insieme complesso di classi [9]. I controllers perciò non implementano alcuna logica di business (vedi lista- to 5.8), tale responsabilità è infatti affidata alle facade MaintenanceFacade e CoreFacade. @PostMapping(value = "/maintenance/sites") @ResponseStatus(HttpStatus.CREATED) public CreateAclSiteResponse createAclSite( @RequestBody CreateAclSiteRequest createAclSiteRequest) { return maintenanceFacade.createAclSite( createAclSiteRequest.getAclSiteName(), createAclSiteRequest.getAclSiteAddress()); } Listato 5.8: Metodo di un rest controller. Come si evince facilmente, non implementa alcuna logica di business Repositories Le classi MaintenanceFacade, CoreFacade e HalApi hanno le proprie repo- sitories, ovvero classi il cui obiettivo è quello di fornire una API pulita per l’accesso ai dati, salvati nel DBMS. Database Per la scrittura del database si è utilizzato il DBMS PostgreSQL, un database object-relational opensource [21] nella sua versione 14.1. Per convertire le 39
  • 41. righe delle tabelle in oggetti Java e per poterli manipolare si è utilizzato l’ORM - Object Relation Mapping Hibernate, nella sua versione 5.6.1 [11]. Per mantenere i due moduli disaccoppiati, ognuno gestisce autonomamente le proprie entità, che sono salvate in tabelle scollegate tra loro. 5.1.5 Interazione tra i moduli ACL e HAL I concetti che sono in comune ad entrambi, che ne constuiscono quindi il vocabolario comune, sono i seguenti • String passageHardwareId • UserDesiredState userDesiredState • String halSiteId Access Control Logic Hardware Abstraction Layer User Desired State Passage Hardware Id Hal Site Id Figura 5.12: Vocabolario condiviso tra HAL e ACL Per fare in modo che i moduli siano più disaccoppiati possibile, il modulo HAL, lavorando ad un livello di astrazione più basso, non ha al suo interno alcun concetto di più alto livello che invece è proprio dell’ACL. 5.1.6 MaintenanceFacade e CoreFacade Le facade MaintenanceFacade e CoreFacade sono in particolare due interfac- ce, implementate rispettivamente dalle classi DefaultMaintenanceFacade e DefaultCoreFacade. Tutte queste classi si trovano all’interno del package 40
  • 42. net.opfa.acl.maintenance. Il codice delle interfacce è riportato nel listato 5.10 e nel listato 5.9. public interface MaintenanceFacade { MaintenanceGraphResponse fetchGraph(String aclSiteId); CreateAclSiteResponse createAclSite(String siteName, String address); CreateRoomResponse createRoom(String aclSiteId, String roomName); CoreRoomResponse deleteRoom(String aclSiteId, String roomId); MaintenancePassageResponse createPassage(String aclSiteId, String startingRoomId, String targetRoomId); CorePassageResponse deletePassage(String aclSiteId, String passageId); AddLockResponse registerLock(String aclSiteId, String passageId, Vendor vendor, String vendorLockId); boolean addVendorSiteToAclSite(String aclSiteId, String vendorSiteId, Vendor vendor, String customerReference); List<HalSiteDto> fetchHalSites(String aclSiteId); List<HalSiteDto> fetchHalSitesNotAssigned(); List<LockResponse> fetchAllVendorLocks(String aclSiteId); boolean existsRoom(String aclSiteId, String roomId); boolean existsPassage(String aclSiteId, String passageId); } Listato 5.9: definizione MaintenanceFacade public interface CoreFacade { Set<PathResponse> findPaths(String aclSiteId, String startRoomId, String destinationRoomId); Set<CredentialType> credentialsForPath(String aclSiteId, List<String> 41
  • 43. passageIdsInPath); Set<CoreSiteResponse> fetchSites(); CreateGrantResponse createGrant(String aclSiteId, String aclUserId, List<String> pathIdAsPassageIds, Date from, Date to); CoreSiteResponse fetchAclSite(String aclSiteId); UserDesiredState computeUserDesiredState(String aclUserId); UserDesiredState computeUserDesiredState(String aclSiteId, String aclUserId); void revokeAccess(String aclSiteId, String grantId); void alignAllGrants(String aclSiteId); boolean canUnlockPathLazy(String aclSiteId, String aclUserId, List<String> pathAsPassageIds); boolean canUnlockPathEager(String aclSiteId, String userId, List<String> passageIdsInPath); boolean canUnlockPassageEager(String aclSiteId, String aclUserId, String passageId); boolean isGrantValid(String grantId); DesiredState computeDesiredState(); Set<CredentialType> credentialsTypesForPath(String aclSiteId, List<String> pathAsPassageIds); Set<Credential> loadUserCredentials(String aclUserId); CoreGraphResponse fetchGraphByAclSiteId(String aclSiteId); Set<GrantResponse> fetchGrants(String aclSiteId); CoreSiteInformationResponse fetchAclSiteInformation(String aclSiteId); } Listato 5.10: Definizione CoreFacade 42
  • 44. 5.1.7 Gestione delle eccezioni Nonostante Java definisca fondamentalmente tutte le tipologie di eccezione che si possono verificare durante l’esecuzione del codice, sono state create delle classi per meglio specificare l’eccezione riscontrata. Tutte le classi create estendono la classe RuntimeException, in modo da non vincolare lo sviluppatore a gestire tali eccezioni esplicitamente. Infatti, se le classi estendessero la classe Exception, sarebbe stato necessario inserire dei blocchi try-catch all’interno del codice oppure aggiungere la clausola throws alla firma dei metodi, rendendo il codice estremamente verboso e meno leggibile. Tali eccezioni sono state inserite nel package net.opfa.exceptions e sono • AclSiteNotFoundException • AclUserNotFoundException • GrantNotFoundException • PassageHardwareNotFoundException • PassageNotFoundException • RoomNotFoundException • AccessGroupNotFoundException • VendorLockNotFoundException • VendorSiteNotFoundException • VendorUserNotFoundException Il modo con cui queste classi sono state scritte è comune: ognuna di esse infatti definisce due costruttori, uno vuoto e uno che prende come input una stringa. Il primo serve a impostare un messaggio di default predefinito, il secondo invece consente di specificarlo. Nel listato 5.11 è stata riportata a titolo di esempio la classe GrantNotFoundException. 43
  • 45. public class GrantNotFoundException extends RuntimeException{ public GrantNotFoundException() { super("Grant not found"); } public GrantNotFoundException(String message) { super(message); } } Listato 5.11: la classe GrantNotFoundException 5.1.8 Test Per testare l’applicazione sono stati scritti diversi test, inseriti nella directory di default prevista da Maven. Ad eccezione della classe RealScenarioTest, tutti i test sono di tipo unitario, ovvero testano un singolo componente software. I moduli testati sono SaltoConnector, SaltoDriver, HalApi, MaintenanceFacade e CoreFacade. Il framework impiegato per l’esecuzione dei test è JUnit, nella sua versione 4.13 [16]. 5.2 Front end Il front end si articola in due single page applications, una dedicata al back office e una dedicata al front office. Si è utilizzato come framework Vue.js nella sua versione 2.6.14, mentre come linguaggio di programmazione si è impiegato Javascript 2015, anche noto come ECMAScript 6 [8]. Per navigare all’interno della stessa pagina si è utilizzato Vue Router, ovvero l’official router del framework [26]. Il frontend interagisce con il back end tramite chiamate REST, che sono state realizzate con Axios, un client HTTP basato sulle javascript promises [4]. Nel listato 5.12 è riportato un esempio tipico di una chiamata axios. axios .get(‘${process.env.BACKEND_URL}/sites/${process.env.ACLSITE_ID}/graph‘) .then(response => this.graph = response.data) 44
  • 46. .catch(error => console.error(error)); Listato 5.12: chiamata axios per ricevere il grafo di un edificio 5.2.1 Comunicazione ad eventi tra i componenti Qualora un componente di vue ne contenga altri che devono comunicare tra loro, la comunicazione è stata gestita per mezzo di eventi. L’evento generato da un componente viene catturato dal componente che lo contiene, per essere indirizzato al componente interessato. Questo è il caso ad esempio del tab relativo alla creazione di un grant, dove una volta selezionato il percorso all’interno del form lo si deve mostrare colorando le stanze e gli archi interessati, che però sono all’interno di un altro componente. 5.2.2 Rappresentazione e costruzione del grafo Per la costruzione e la rappresentazione del cartina si è utilizzato Data-Driven Documents, o d3.js, una libreria javascript per la manipolazione di documenti basata sui dati. Tale libreria è molto vasta e consente la rappresentazione di diversi grafici e non solo. In particolare si è utilizzato il force directed graph [7] (vedi listato 5.13). this.simulation = d3 .forceSimulation(rooms) .force("charge", d3.forceManyBody().strength(-1000)) .force("link", d3.forceLink(passages) .distance(200) .id(passage => passage.id)) .force("x", d3.forceX()) .force("y", d3.forceY()) .force("center", d3.forceCenter(width / 2, height / 2)) .on("tick", tickFunction) Listato 5.13: lancio della simulazione di un force directed graph. Utilizzato per mostrare a schermo il grafo rappresentante la cartina. 45
  • 47. 5.3 Estetica delle pagine web Per come vengono rappresentate le pagine web si è utilizzato BootstrapVue, una libreria di componenti basata interamente sul front end framework css Bootstrap, nella sua versione 4.5 [5]. All’interno dei singoli componenti tutta- via è possibile trovare del css specifico del componente stesso. Quest’ultimo, se presente, è individuato dalla sezione <style scoped> css code </style> Per differenziare l’interfaccia del back office da quella del front office si sono utilizzati dei temi diversi, forniti da Bootswatch [6], una collezione di temi open source per Bootstrap. Per il front office si è utilizzato il tema zephyr, mentre per il back office il tema sandstone. 5.4 Sistema di controllo di versione Si è utilizzato come sistema di controllo di versione git, un version control system gratuito e open source [10]. La locazione di tutto il codice sviluppa- to risiede nella repository ”building-access-control”, proprietà dell’account GitHub aziendale, all’indirizzo https://github.com/optionfactory/building-access-control la repository tuttavia è privata, per cui non è visibile. All’interno della repository sono presenti tre progetti: i due progetti vue per il front office e il progetto maven del back office. 5.5 Validazione del software Per verificare la correttezza del software nella sua interezza è stato scritto un test di sistema, che cerca il più possibile di testare il software nella sua interezza. Il test prende il nome di RealScenarioTest, e comincia con la costru- zione del sito e delle sue stanze e passaggi, aggiungendo su alcuni di essi dei lucchetti. Il test prosegue con l’assegnazione di un grant ad un utente, l’applicazione dello stato desiderato seguito dalla revoca del grant appena assegnato. 46
  • 48. public class RealScenarioTest { private MaintenanceFacade maintenanceFacade; private AclSitesRepository aclSitesRepository; private CoreFacade coreFacade; private AclUsersRepository aclUsersRepository; private GrantsRepository grantsRepository; private PassageHardwareRepository passageHardwareRepository; private HalApi halApi; @Before public void setup() { // creazione delle dipendenze aclSitesRepository = new InMemoryAclSiteRepository(); grantsRepository = new InMemoryGrantsRepository(); aclUsersRepository = new InMemoryAclUserRepository(); passageHardwareRepository = new PassageHardwareRepository .InMemoryPassageHardwareRepository(); halApi = new HalApi( passageHardwareRepository, new FakeSaltoConnector()); maintenanceFacade = new DefaultMaintenanceFacade( aclSitesRepository, halApi); coreFacade = new DefaultCoreFacade( aclSitesRepository, aclUsersRepository, grantsRepository, halApi); } @Test public void testScenario() { // Parte manutenzione 47
  • 49. // creazione del sito final String aclSiteId = maintenanceFacade .createAclSite("Option Factory", "Via Beccaria, 6") .getAclSiteId(); final AclSite aclSite = aclSitesRepository .findAclSiteById(aclSiteId) .orElseThrow(AclSiteNotFoundException::new); Assert.assertNotNull(aclSite); // creazione delle stanze final Room outsideRoom = aclSite.getOutside(); final String outsideId = outsideRoom.getId(); final String hallId = maintenanceFacade .createRoom(aclSiteId, "hall").getRoomId(); // ... segue la creazione delle altre stanze Assert.assertTrue(maintenanceFacade .existsRoom(aclSiteId, outsideId)); Assert.assertTrue(maintenanceFacade .existsRoom(aclSiteId, hallId)); // ... seguono gli altri assert per le altre stanze create // Creazione dei passaggi final String outsideHallId = maintenanceFacade .createPassage(aclSiteId, outsideId, hallId) .getId(); // ... segue la creazione degli altri passaggi Assert.assertTrue(maintenanceFacade .existsPassage(aclSiteId, outsideHallId)); // ... seguono gli altri assert degli altri passaggi // ricerca di un vendor site final HalSiteDto halSiteDtoSalto = maintenanceFacade .fetchHalSitesNotAssigned() .stream() .filter(halSite -> halSite .getCustomerReference() .equals("Option Factory - SALTO")) .findFirst() 48
  • 50. .orElseThrow(VendorSiteNotFound::new); Assert.assertTrue(maintenanceFacade .addVendorSiteToAclSite( aclSiteId, halSiteDtoSalto.getVendorSiteId(), halSiteDtoSalto.getVendor(), halSiteDtoSalto.getCustomerReference() )); // registrazione dei locks final String vendorLock1Id = maintenanceFacade .fetchAllVendorLocks(aclSiteId) .stream() .filter(lockResponse -> lockResponse .getDescription() .equals("activation code 1")) .findFirst() .orElseThrow(VendorLockNotFoundException::new) .getId(); final String vendorLock2Id = maintenanceFacade .fetchAllVendorLocks(aclSiteId) .stream() .filter(lockResponse -> lockResponse .getDescription() .equals("activation code 2")) .findFirst() .orElseThrow(VendorLockNotFoundException::new) .getId(); final String vendorLock3Id = maintenanceFacade .fetchAllVendorLocks(aclSiteId) .stream() .filter(lockResponse -> lockResponse .getDescription() .equals("activation code 3")) .findFirst() .orElseThrow(VendorLockNotFoundException::new) .getId(); final String vendorLock4Id = maintenanceFacade .fetchAllVendorLocks(aclSiteId) 49
  • 51. .stream() .filter(lockResponse -> lockResponse .getDescription() .equals("activation code 4")) .findFirst() .orElseThrow(VendorLockNotFoundException::new) .getId(); maintenanceFacade.registerLock( aclSiteId, office1Hallway1Id, Vendor.SALTO, vendorLock1Id); // ... segue la registrazione degli altri vendor locks Assert.assertFalse(aclSite.getPassage(hallHallWay1Id) .orElseThrow(PassageNotFoundException::new) .getPassageHardwareId().isPresent()); // ... analogamente seguono le altre asserzioni Assert.assertTrue(halApi.isLockRegistered( aclSite.getHalSiteIds(), vendorLock1Id)); // ... analogamente seguono le altre asserzioni final List<String> allPassagesIds = aclSite .getAllPassages() .stream() .map(Passage::getId) .collect(Collectors.toList()); Assert.assertTrue(coreFacade .credentialsTypesForPath(aclSiteId, allPassagesIds) .contains(CredentialType.PIN)); Assert.assertFalse(coreFacade .credentialsTypesForPath(aclSiteId, allPassagesIds) .contains(CredentialType.BLE)); Assert.assertFalse(coreFacade .credentialsTypesForPath(aclSiteId, allPassagesIds) .contains(CredentialType.NFC)); Assert.assertFalse(coreFacade 50
  • 52. .credentialsTypesForPath(aclSiteId, allPassagesIds) .contains(CredentialType.RFID)); // parte core final String externalUserId = UUID.randomUUID().toString(); // Ricerca di tutti i passaggi dall’outside alla meeting room final Set<List<String>> allForwardPathsAsPassageIds = coreFacade .findPaths(aclSiteId, outsideId, meetingRoomId) .stream() .map(PathResponse::getPathAsPassageIds) .collect(Collectors.toSet()); Assert.assertEquals(2, allForwardPathsAsPassageIds.size()); final List<String> selectedForwardPathAsPassageIds = allForwardPathsAsPassageIds .stream() .filter(forwardPathAsPassageIds -> forwardPathAsPassageIds .contains(hallway2MeetingRoomAId)) .findFirst() .orElseThrow(() -> new IllegalStateException("No forward path found")); final Set<List<String>> allBackwardPathsAsPassageIds = coreFacade .findPaths(aclSiteId, meetingRoomId, outsideId) .stream() .map(PathResponse::getPathAsPassageIds) .collect(Collectors.toSet()); final List<String> selectedBackwardPathAsPassageIds = allBackwardPathsAsPassageIds.stream() .findFirst() .orElseThrow(() -> new IllegalStateException("No backward path found")); final List<String> selectedCompletePathAsPassageIds = Stream .concat(selectedForwardPathAsPassageIds.stream(), selectedBackwardPathAsPassageIds.stream()) .collect(Collectors.toList()); final List<String> passageHardwareIdsOfCompletePath = selectedCompletePathAsPassageIds .stream() 51
  • 53. .map(aclSite::getPassage) .map(passage -> passage .orElseThrow(PassageHardwareNotFoundException::new)) .map(Passage::getPassageHardwareId) .filter(Optional::isPresent) .map(Optional::get) .collect(Collectors.toList()); // assegnazione di un grant valido per una settimana final Date startDate = new Date(); final long oneWeekInMilliseconds = 1000 * 60 * 60 * 24 * 7; final Date endDate = new Date( System.currentTimeMillis() + oneWeekInMilliseconds); final CreateGrantResponse createGrantResponse = coreFacade .createGrant( aclSiteId, externalUserId, selectedCompletePathAsPassageIds, startDate, endDate); Assert.assertTrue(coreFacade .isGrantValid(createGrantResponse.getId())); final UserDesiredState userDesiredState = coreFacade .computeUserDesiredState(aclSiteId, externalUserId); Assert.assertEquals( userDesiredState.getPassageHardwareIds(), new HashSet<>(passageHardwareIdsOfCompletePath)); Assert.assertTrue(coreFacade .canUnlockPathLazy( aclSiteId, externalUserId, selectedForwardPathAsPassageIds)); Assert.assertTrue(coreFacade.canUnlockPathEager( aclSiteId, externalUserId, selectedForwardPathAsPassageIds)); final Set<CredentialType> userCredentialsTypes = coreFacade .loadUserCredentials(externalUserId) 52
  • 54. .stream() .map(Credential::getType) .collect(Collectors.toSet()); Assert.assertTrue(userCredentialsTypes .contains(CredentialType.PIN)); Assert.assertFalse(userCredentialsTypes .contains(CredentialType.BLE)); Assert.assertFalse(userCredentialsTypes .contains(CredentialType.NFC)); // revoca del grant: lo user desired state deve essere vuoto coreFacade.revokeAccess(aclSiteId, createGrantResponse.getId()); Assert.assertTrue(coreFacade .computeUserDesiredState(aclSiteId, externalUserId) .isEmpty()); } } Listato 5.14: codice di RealScenarioTest 53
  • 55. Capitolo 6 Conclusioni Gli obiettivi prefissati sono stati raggiunti solo parzialmente. Il progetto purtroppo si è rivelato molto più complicato del previsto, per cui non tutti i punti individuati sono stati raggiunti. Molte parti del software infatti sono solamente simulate, come l’interazione con le piattaforme dei vendors. Inol- tre, dei vari vendors studiati, è stato scritto soltanto un driver, ovvero quello del vendor SALTO KS [23]. Complessivamente si è soddisfatti del lavoro svolto, in quanto si è riuscito a esplorare il problema nella sua complessità e nella sua eterogeneità. Questo ha portato alla realizzazione di un software che, sebbene incompleto, fornisce una corretta astrazione del problema. Qualora si volesse dare quindi conti- nuità al progetto, il software scritto costituisce un valido punto di riferimento da cui partire. La realizzazione della demo consente di dare un’idea sufficiente di quello che, se realizzato, sarà il progetto finale. Molte delle funzionalità mostrate non sono state implementate, essenzialmente per motivi di tempo, come ad esempio la possibilità di rimuovere i passaggi e di aggiungere metadati alle stanze. Avendo sviluppato il software alla Option Factory S.r.l. ho avuto modo di conoscere una realtà aziendale, profondamente diversa da quella universita- ria. Questo mi ha dato la possibilità di capire quale sia l’ambiente lavorativo al quale sono interessato ma soprattutto il settore lavorativo in cui c’è la volontà di inserirsi. 54
  • 56. Nei tre mesi di tirocinio ho avuto modo di ampliare molto le mie conoscen- ze e di mettere in pratica quelle apprese all’università, apprendendo nuove tecnologie e affrontando di volta in volta le varie problematiche che si presen- tavano, da quelle prettamente tecniche alle scelte progettuali. Mansioni come la consultazione della documentazione del software e la scrittura del codice hanno avuto infine un impatto importante per la mia crescita personale e in futuro professionale. 55
  • 57. Bibliografia [1] Apache Maven. url: https://maven.apache.org/. visitato il giorno: 21.01.2022. [2] Apache Tomcat. url: https : / / tomcat . apache . org/. visitato il giorno: 21.01.2022. [3] APlus. url: https://www.aplus.srl/. visitato il giorno: 21.01.2022. [4] Axios. url: https://axios-http.com/. visitato il giorno: 21.01.2022. [5] Bootstrap 4.5 documentation. url: https : / / getbootstrap . com / docs / 4 . 5 / getting - started / introduction/. visitato il giorno: 21.01.2022. [6] Bootswatch. url: https://bootswatch.com/. visitato il giorno: 21.01.2022. [7] Mike Bostok. Force-Directed-Graph. url: https://observablehq. com/@d3/force-directed-graph. visitato il giorno: 21.01.2022. [8] ECMAScript 6. url: https://www.w3schools.com/js/js_es6.asp. visitato il giorno: 21.01.2022. [9] Facade Design Pattern. url: https://refactoring.guru/design- patterns/facade. visitato il giorno: 21.01.2022. [10] Git. url: https://git-scm.com/. visitato il giorno: 21.01.2022. [11] Hibernate Site. url: https://hibernate.org/. visitato il giorno: 21.01.2022. [12] IntelliJ IDEA. url: https://www.jetbrains.com/idea/. visitato il giorno: 21.01.2022. [13] JavaScript. url: https://www.javascript.com/. visitato il giorno: 21.01.2022. [14] JGraphT. url: https://jgrapht.org/. visitato il giorno: 21.01.2022. 56
  • 58. [15] JSON. url: https://www.json.org/json-en.html. visitato il giorno: 21.01.2022. [16] JUnit. url: https://junit.org/junit5/docs/current/user- guide/. visitato il giorno: 21.01.2022. [17] Manifesto per lo sviluppo agile del software. url: https://agilemanifesto. org/iso/it/manifesto.html. visitato il giorno: 21.01.2022. [18] OpenPath. url: https : / / www . openpath . com/. visitato il giorno: 21.01.2022. [19] Option Factory. url: https://www.optionfactory.net/. visitato il giorno: 21.01.2022. [20] Owler. url: https://corp.owler.com/. visitato il giorno: 21.01.2022. [21] PostgreSQL. url: https://www.postgresql.org/. visitato il giorno: 21.01.2022. [22] REST APIs. url: https://www.redhat.com/it/topics/api/what- is-a-rest-api. visitato il giorno: 21.01.2022. [23] Salto KS. url: https://saltoks.com/. visitato il giorno: 21.01.2022. [24] Spring Framework. url: https://spring.io/projects/spring- framework. visitato il giorno: 21.01.2022. [25] Visual Studio Code. url: https://code.visualstudio.com/. visitato il giorno: 21.01.2022. [26] Vue Router Documentation. url: https : / / router . vuejs . org/. visitato il giorno: 21.01.2022. [27] Vue.js. url: https://vuejs.org/. visitato il giorno: 21.01.2022. 57