| /******************************************************************************* |
| * Copyright (C) 2007 The University of Manchester |
| * |
| * Modifications to the initial code base are copyright of their |
| * respective authors, or their employers as appropriate. |
| * |
| * This program is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Lesser General Public License |
| * as published by the Free Software Foundation; either version 2.1 of |
| * the License, or (at your option) any later version. |
| * |
| * This program is distributed in the hope that it will be useful, but |
| * WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Lesser General Public License for more details. |
| * |
| * You should have received a copy of the GNU Lesser General Public |
| * License along with this program; if not, write to the Free Software |
| * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 |
| ******************************************************************************/ |
| package net.sf.taverna.t2.workbench.ui.credentialmanager; |
| |
| import static javax.swing.JOptionPane.ERROR_MESSAGE; |
| import static javax.swing.JOptionPane.showMessageDialog; |
| import static net.sf.taverna.t2.security.credentialmanager.CredentialManager.KeystoreType.KEYSTORE; |
| import static net.sf.taverna.t2.workbench.ui.credentialmanager.CMStrings.ERROR_TITLE; |
| import static net.sf.taverna.t2.workbench.ui.credentialmanager.CredentialManagerUI.PASSWORD_ENTRY_TYPE; |
| |
| import java.net.URI; |
| import java.util.TreeMap; |
| |
| import javax.swing.JFrame; |
| import javax.swing.table.AbstractTableModel; |
| |
| import net.sf.taverna.t2.lang.observer.Observable; |
| import net.sf.taverna.t2.lang.observer.Observer; |
| import net.sf.taverna.t2.security.credentialmanager.CMException; |
| import net.sf.taverna.t2.security.credentialmanager.CredentialManager; |
| import net.sf.taverna.t2.security.credentialmanager.KeystoreChangedEvent; |
| import net.sf.taverna.t2.security.credentialmanager.UsernamePassword; |
| |
| import org.apache.log4j.Logger; |
| |
| /** |
| * The table model used to display the Keystore's username/password pair |
| * entries. |
| * |
| * @author Alex Nenadic |
| */ |
| @SuppressWarnings("serial") |
| public class PasswordsTableModel extends AbstractTableModel implements |
| Observer<KeystoreChangedEvent> { |
| private static final Logger logger = Logger |
| .getLogger(PasswordsTableModel.class); |
| |
| // Column names |
| private String[] columnNames; |
| // Table data |
| private Object[][] data; |
| private CredentialManager credManager; |
| |
| public PasswordsTableModel(CredentialManager credentialManager) { |
| credManager = credentialManager; |
| if (credentialManager == null) { |
| // Failed to instantiate Credential Manager - warn the user and exit |
| String sMessage = "Failed to instantiate Credential Manager. "; |
| logger.error("CM GUI: " + sMessage); |
| showMessageDialog(new JFrame(), sMessage, ERROR_TITLE, |
| ERROR_MESSAGE); |
| return; |
| } |
| |
| data = new Object[0][0]; |
| columnNames = new String[] { "Entry Type", // type of the Keystore entry |
| "Service URL", // the service url, part of the actual alias in |
| // the Keystore |
| "Username", // username for the service, part of the password |
| // entry in the Keystore |
| "Last Modified", // last modified date of the entry |
| "Password", // the invisible column holding the password value |
| // of the password entry in the Keystore |
| "Alias" // the invisible column holding the Keystore alias of |
| // the entry |
| }; |
| |
| try { |
| load(); |
| } catch (CMException cme) { |
| String sMessage = "Failed to load username and password pairs"; |
| logger.error(sMessage); |
| showMessageDialog(new JFrame(), sMessage, ERROR_TITLE, |
| ERROR_MESSAGE); |
| return; |
| } |
| |
| // Start observing changes to the Keystore |
| credManager.addObserver(this); |
| } |
| |
| /** |
| * Load the PasswordsTableModel with the password entries from the Keystore. |
| */ |
| public void load() throws CMException { |
| // Place password entries' aliases in a tree map to sort them |
| TreeMap<String, String> aliases = new TreeMap<>(); |
| |
| for (String alias : credManager.getAliases(KEYSTORE)) |
| /* |
| * We are only interested in username/password entries here. Alias |
| * for such entries is constructed as "password#"<SERVICE_URL> where |
| * service URL is the service this username/password pair is to be |
| * used for. |
| */ |
| if (alias.startsWith("password#")) |
| aliases.put(alias, alias); |
| |
| // Create one table row for each password entry |
| data = new Object[aliases.size()][6]; |
| |
| /* |
| * Iterate through the sorted aliases, retrieving the password entries |
| * and populating the table model |
| */ |
| int iCnt = 0; |
| for (String alias : aliases.values()) { |
| /* |
| * Populate the type column - it is set with an integer but a custom |
| * cell renderer will cause a suitable icon to be displayed |
| */ |
| data[iCnt][0] = PASSWORD_ENTRY_TYPE; |
| |
| /* |
| * Populate the service URL column as a substring of alias from the |
| * first occurrence of '#' till the end of the string |
| */ |
| String serviceURL = alias.substring(alias.indexOf('#') + 1); |
| data[iCnt][1] = serviceURL; |
| |
| /* |
| * Get the username and password pair from the Keystore. They are |
| * returned in a single string in format |
| * <USERNAME><SEPARATOR_CHARACTER><PASSWORD> |
| */ |
| UsernamePassword usernamePassword = credManager |
| .getUsernameAndPasswordForService(URI.create(serviceURL), |
| false, ""); |
| String username = usernamePassword.getUsername(); |
| String password = usernamePassword.getPasswordAsString(); |
| |
| // Populate the username column |
| data[iCnt][2] = username; |
| |
| // Populate the last modified date column ("UBER" keystore type |
| // supports creation date) |
| // data[iCnt][3] = |
| // credManager.getEntryCreationDate(CredentialManager.KEYSTORE, |
| // alias); |
| |
| // Populate the invisible password column |
| data[iCnt][4] = password; |
| |
| // Populate the invisible alias column |
| data[iCnt][5] = alias; |
| |
| iCnt++; |
| } |
| |
| fireTableDataChanged(); |
| } |
| |
| /** |
| * Get the number of columns in the table. |
| */ |
| @Override |
| public int getColumnCount() { |
| return columnNames.length; |
| } |
| |
| /** |
| * Get the number of rows in the table. |
| */ |
| @Override |
| public int getRowCount() { |
| return data.length; |
| } |
| |
| /** |
| * Get the name of the column at the given position. |
| */ |
| @Override |
| public String getColumnName(int iCol) { |
| return columnNames[iCol]; |
| } |
| |
| /** |
| * Get the cell value at the given row and column position. |
| */ |
| @Override |
| public Object getValueAt(int iRow, int iCol) { |
| return data[iRow][iCol]; |
| } |
| |
| /** |
| * Get the class at of the cells at the given column position. |
| */ |
| @Override |
| public Class<? extends Object> getColumnClass(int iCol) { |
| return getValueAt(0, iCol).getClass(); |
| } |
| |
| /** |
| * Is the cell at the given row and column position editable? |
| */ |
| @Override |
| public boolean isCellEditable(int iRow, int iCol) { |
| // The table is always read-only |
| return false; |
| } |
| |
| @Override |
| public void notify(Observable<KeystoreChangedEvent> sender, |
| KeystoreChangedEvent message) throws Exception { |
| // reload the table |
| if (message.keystoreType.equals(KEYSTORE)) |
| load(); |
| } |
| } |