Sugar come sistema di autenticazione Demo disponibile : è ora possibile provare direttamente quanto spiegato in questo articolo. Una demo è disponibile qui. Introduzione Eccoci di nuovo con questa serie di articoli sull'integrazione di SugarCRM. Questa volta esploreremo l'utilizzo di sugar come sistema di autenticazione e gestore di utenti per applicativi PHP. Partendo dalla classe php sviluppata nel primo articolo, la espanderemo con alcune funzionalità; poi potremo scrivere del codice di base da usare nei nostri applicativi per comunicare con sugar. In sostanza, avremo una form di registrazione sul nostro applicativo web, che compilata creerà un "Contatto" su sugar assegnandogli una password indicata. Per l'attivazione effetiva dell'utente, un utente sugar dovrà entrare nel crm e settare un apposito checkbox che andremo a creare a breve. Questo è l'essenziale, molte altre funzionalità possono aggiungersi tipo: email di notifica, gruppi di utenti, uno stato utente più articolato (non solo attivo/non attivo) etc., ma questo lo lasciamo allo sviluppatore dell'applicativo php. Ancora una volta l'interfaccia SOAP di sugar sarà il nostro coltellino svizzero.
Configurazione di Sugar Useremo il modulo "Contatti" di sugar come archivio dei nostri utenti. Su sugar abbiamo bisogno di un paio di nuovi campi personalizzati: un campo di testo per la password e una checkbox per abilitare/disabilitare l'accesso dell'utente al nostro applicativo. Da notare che quando scrivo "utente" mi riferisco ad un utilizzatore del nostro applicativo php, non ad un utente sugar. Per chiarire, gli utenti sugar sono quelli che possono fare un log in nell'interfaccia di SugarCRM. I nostri utenti invece sono quelli che su sugar compaiono come "Contatti". Dopo aver creato i campi personalizzati dobbiamo aggiungere la checkbox al pannello EditView del modulo Contatti di sugar, per poterlo realmente utilizzare. Non preoccupatevi se questo non è chiaro. Ho preparato un'animazione con wink con i dettagli del processo. Potete vederla qui. Ora dal lato sugar siamo pronti. Che funzionialità SOAP useremo questa volta? Abbiamo già visto (vedere il precedente articolo) come interrogare sugar via SOAP, quindi siamo in grado di controllare se un utente esiste ed è abilitato, ora abbiamo bisogno di scrivere su sugar(creazione di un nuovo utente). Il nostro metodo SOAP è set_entry. Vediamo il nuovo codice da aggiungere alla classe SugarSoap....
Nuovi metodi nella classe SugarSoap Prima aggiungiamo un metodo generico setEntry che verrà utilizzato per scrivere sui vari moduli sugar:
/** * Modify sugar entry with given data(used by other set### functions) * **/ function setEntry($module,$array){ $data_array=array(); while(list($name,$value)=each($array)){ $data_array[]= array( 'name' => $name, 'value' => $value ); } $result = $this->proxy->set_entry( $this->sess, $module, $data_array ); return $result; }
Il metodo set_entry dell'interfaccia soap di sugar richiede 3 parametri: - Un id di sessione valido
- Il nome del modulo (es. Contatti)
- L'array di dati in formato sugar(una coppia name/value per ogni campo)
Al nostro metodo setEntry passiamo un array associativo, quindi il ciclo "while" lo trasforma in un array accettato da sugar. Una nota su set_entry: se viene passato un campo "id" nel parametro data_array, sugar farà un aggiornamento del record corrispondente all'id dato, altrimenti intenderà la chiamata come un inserimento e creerà un nuovo record. Ora possiamo aggiungere metodi "setXXX" facilmente per i moduli che ci interessano. In questo caso:
function setContact($array){ return $this->setEntry("Contacts",$array); } La classe di autenticazione Ciò che ci serve è una semplice classe che gestisca la creazione di utenti e l'autenticazione di utenti esistenti. Eccone una bozza:
<?php include_once "SugarSoap.php"; class UserManagement{ var $soap; function UserManagement(){ // here goes your sugar installation address $this->soap=new SugarSoap('http://mysugar/soap.php?wsdl'); } function authenticate($email,$password){ $result=$this->soap->getContacts(" contacts_cstm.can_login_c='1' and contacts.email1='".$email."' and contacts_cstm.password_c='".$password."'", 1,""); if($result['result_count']>0){ // Authenticated // transform return values into an associative array $result=$this->soap->nameValuePairToSimpleArray( $result['entry_list'][0]['name_value_list']); /** * Here we can add code for managing the authenticated user, * for example put some user data in a session variable * (id, first and last name, email etc.) * Something like this: **/ $_SESSION['user_data']=$result; return true; } else{ // Not authenticated /** * and here we can add code for managing the authentication error, * for example a notification email to someone **/ return false; } } } ?>
Concentriamoci sul metodo "authenticate". Questo è ovviamente usato per controllare le credenziali di un utente che stia cercando di entrare nel nostro applicativo. Quando viene chiamato "getContacts", controlliamo che l'utente sia autorizzato (can_login=1) e che email e password siano corretti. Se così è, il campo result_count sarà maggiore di zero. In un ipotetico processo di registrazione utenti abbiamo anche bisogno di un metodo createUser che si aspetti almeno una email e una password. Eccolo: function createUser($email,$password){ return $this->soap->setContact(array( "email1" => $email, "password_c" => $password )); } Ricordiamoci che il campo email del modulo "Contatti" si chiama email1 e che la password è il campo personalizzato password_c che abbiamo creato.
Una bozza di pagina web di registrazione utente A questo punto abbiamo tutte le basi per gestire un processo di autenticazione. Una semplice pagina "register.php" potrebbe essere qualcosa tipo questo: <?php /** * Trivial and incomplete example of * user registration. Missing are lots of * things, like password confirmation or * checking that a user with the same email * is already registered on the system * **/ if(isset($_POST['submit'])){ require_once "UserManagement.php"; $usman=new UserManagement(); $usman->createUser($_POST['email'],$_POST['password']); echo "User created"; die(); }
?> <html> <body> <form method=POST> <table> <tr> <td>Email</td> <td><input type=text name=email></td> </tr> <tr> <td>Password</td> <td><input type=password name=password></td> </tr> <tr> <td colspan=2 align=center> <input type=submit name=submit value="Register"> </td> </tr> </table> </form> </body> </html> L'utente appena creato non potrà fare login sul sistema perchè il campo personalizzato can_login_c è di default a 0. Un utente sugar dovrà autorizzarlo dal modulo Contatti. In un processo completo ci saranno anche email di notifica, controlli dei campi e altri controlli di sicurezza.
Una pagina di login d'esempio sarà del tipo: <?php /** * Similar notes as for the registration * page. **/ if(isset($_POST['submit'])){ require_once "UserManagement.php"; $usman=new UserManagement(); if($usman->authenticate($_POST['email'],$_POST['password'])){ echo "User authenticated"; }else { echo "Authentication error"; } die(); }
?> <html> <body> <form method=POST> <table> <tr> <td>Email</td> <td><input type=text name=email></td> </tr> <tr> <td>Password</td> <td><input type=password name=password></td> </tr> <tr> <td colspan=2 align=center> <input type=submit name=submit value="Login"> </td> </tr> </table> </form> </body> </html> Dovrebbe essere abbastanza auto esplicativa. Da qui dovrebbe essere semplice costruire un sistema di autenticazione robusto, comodo e facile da gestire. Come abbiamo visto, la quantità di codice da scrivere e piuttosto bassa, perchè gran parte del lavoro è demandato a sugar. Ci sono numerose funzionalità da aggiungere per rendere il sistema più completo. Eccone alcune: - Password encodate(md5 o sha). Questo assicurerebbe un maggior livello di sicurezza in caso di tampering del db, ma renderebbe impossibile il recupero delle password.
Molti fattori possono influenzare la scelta di uno o dell'altro metodo. - Un campo di stato utente, invece di una semplice checkbox attivo/non attivo, ad esempio per avere stati di: in attesa di approvazione, attivo, bloccato, revocato.
In questo caso sarà necessario creare un campo a tendina(dropdown) in sugar. - Un campo gruppo, per implementare differenti privilegi per differenti utenti.
e così via. Spero che la panoramica sia abbastanza chiara da permettere a chiunque di costruire il proprio sistema facilmente.
Prima di chiudere l'articolo Volevo solo nominare un altro utile metodo dell'interfaccia soap di sugar. Parlo di get_module_fields. Questo semplice metodo accetta come parametri un id di sessione e un nome di modulo, e restituisce la lista dei campi del modulo indicato. Questo è piuttosto utile durante lo sviluppo su sugar/soap. Non scriverò codice al riguardo perchè già sappiamo come fare..... |