giovedì 25 novembre 2010

Eclipse RCP Preferences: memorizzare informazioni di login in uno splash screen interattivo

Eclipse RCP mette a disposizione dello sviluppatore un sistema complesso di preferenze che possono essere usate per salvare, ad esempio, informazioni di login. Le preferenze di Eclipse possono essere di due tipi fondamentali:
  • in chiaro
  • cifrate
Le ultime vengono salvate con un meccanismo a keyring e i plugin *.security forniscono tutti gli strumenti necessari al loro utilizzo. Ad esempio org.eclipse.equinox.security.ui permette la memorizzazione nel portachiavi con tanto di dialog per la configurazione del portachiavi stesso. 
Si pone tuttavia un problema per l'utilizzo delle preferenze cifrate: il workspace deve esistere ed essere in esecuzione. Ciò significa che lo sviluppatore ha piu' lavoro da svolgere nel caso in cui le preferenze siano usate da applicazioni RCP headless o, come nel mio caso, da splash screen interattivi (che agiscono prima del workspace stesso).
Qui sotto riporto un esempio di utilizzo di un motore di salvataggio/caricamento dei dati dell'ultimo utente che ha effettuato il login nell'applicazione. In questo caso occorrerebbe salvare i dati in modo cifrato, ma essendo il mio un caso di splash screen interattivo, e trattandosi di dati comunque non fondamentali (poiché nella mia applicazione esistono altri meccanismi di sicurezza), ho deciso di usare per semplicità le preferenze in testo semplice. Da notare che il motore qui sotto proposto estrae ed inserisce i dati in un oggetto User che funge da wrapper per la business logic dietro all'utente stesso.


public class UserPreferencesStorage {

    private String PREFERENCES_USER_ROOT_NODE = "saved-user";
    private String PREFERENCES_USERNAME_NODE  = "username";
    private String PREFERENCES_PASSWORD_NODE  = "password";
    private String PREFERENCES_USER_PK_NODE   = "userpk";

 
    /**
     * Saves the preferences of the provided user.
     * @param user the user that must contain the password and the username to store
     * @return true if the storage has been done
     */
    public boolean saveUserPreferences( User user ) throws BackingStoreException{
 try{
     // get the normal preferences and the scope for this plugin
     IEclipsePreferences preferences = new ConfigurationScope().getNode( Activator.PLUGIN_ID );
     // now get the main node for the configuration storage
     Preferences savedPreferences = preferences.node(PREFERENCES_USER_ROOT_NODE);

     // now store the username and the password
     savedPreferences.put( PREFERENCES_USERNAME_NODE, user.getUsername() ); 
     savedPreferences.put( PREFERENCES_PASSWORD_NODE, user.getPassword() ); 
     savedPreferences.put( PREFERENCES_USER_PK_NODE, user.getPrimaryKey() + "" );  
     
     // flush the storage to ensure everything is written to disk
     preferences.flush();
     
     // all done
     return true;
     
 }catch( BackingStoreException se ){
     // log the exception and do nothing, cannot save
     IStatus status = new Status( IStatus.ERROR,     // severity
      Activator.PLUGIN_ID,      // the id of the application/plug-ing
      "Errore nel salvataggio delle preferenze di login utente",  // message
      se
     );

     throw se;
 }

    }
    
    
    /**
     * Loads a user from the prefences store.
     * @return the user loaded or null
     */
    public User loadUser() throws StorageException{
 // get the normal preferences and the scope for this plugin
 IEclipsePreferences preferences = new ConfigurationScope().getNode( Activator.PLUGIN_ID );
 // now get the main node for the configuration storage
 Preferences savedPreferences = preferences.node(PREFERENCES_USER_ROOT_NODE);
 
 // get the values from the storage
 String username  = savedPreferences.get(PREFERENCES_USERNAME_NODE, "");
 String password  = savedPreferences.get(PREFERENCES_PASSWORD_NODE, "");
 String primaryKey  = savedPreferences.get(PREFERENCES_USER_PK_NODE, "0");
 
 
 // create the user with such values
 User user = new User( Integer.parseInt(primaryKey), username, password );
 
 // all done
 return user;
    }
}

Nessun commento: