/* * RapidMiner * * Copyright (C) 2001-2014 by RapidMiner and the contributors * * Complete list of developers available at our web site: * * http://rapidminer.com * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see http://www.gnu.org/licenses/. */ package com.rapidminer.gui.tools; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.net.PasswordAuthentication; import java.util.logging.Level; import javax.swing.JCheckBox; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JTextField; import javax.swing.SwingUtilities; import com.rapidminer.RapidMiner; import com.rapidminer.gui.security.UserCredential; import com.rapidminer.gui.security.Wallet; import com.rapidminer.gui.tools.dialogs.ButtonDialog; import com.rapidminer.tools.LogService; import com.rapidminer.tools.PasswortInputCanceledException; /** Dialog asking for username and passwords. Answers may be cached (if chosen by user). * * @author Simon Fischer * */ public class PasswordDialog extends ButtonDialog { private static final long serialVersionUID = 1L; private JTextField usernameField = new JTextField(20); private JPasswordField passwordField = new JPasswordField(20); private JCheckBox rememberBox = new JCheckBox(new ResourceActionAdapter("authentication.remember")); private PasswordDialog(String i18nKey, UserCredential preset, Object... args) { super(i18nKey, args); setModal(true); if ((preset != null) && (preset.getPassword() != null)) { usernameField.setText(preset.getUsername()); } if ((preset != null) && (preset.getPassword() != null)) { passwordField.setText(new String(preset.getPassword())); rememberBox.setSelected(true); } String url = (preset != null) ? preset.getURL() : null; JPanel main = new JPanel(new GridBagLayout()); GridBagConstraints c = new GridBagConstraints(); c.fill = GridBagConstraints.BOTH; c.anchor = GridBagConstraints.FIRST_LINE_START; c.insets = new Insets(4, 4, 4, 4); JLabel label = new ResourceLabel("authentication.username", url); label.setLabelFor(usernameField); c.gridwidth = GridBagConstraints.RELATIVE; main.add(label, c); c.gridwidth = GridBagConstraints.REMAINDER; main.add(usernameField, c); label = new ResourceLabel("authentication.password", url); label.setLabelFor(passwordField); c.gridwidth = GridBagConstraints.RELATIVE; main.add(label, c); c.gridwidth = GridBagConstraints.REMAINDER; main.add(passwordField, c); main.add(rememberBox, c); layoutDefault(main, makeOkButton(), makeCancelButton()); } public PasswordAuthentication makeAuthentication() { return new PasswordAuthentication(usernameField.getText(), passwordField.getPassword()); } public static PasswordAuthentication getPasswordAuthentication(String forUrl, boolean forceRefresh) throws PasswortInputCanceledException { return getPasswordAuthentication(forUrl, forceRefresh, false); } /** * @param id the ID to accompany the given url. Used to differentiate multiple entries for the same url. * @param i18nKey The i18nKey has to look like every dialog i18n: gui.dialog.KEY.title etc. * @param args Will be used when i18nKey is set. If i18nKey is <code>null</code> it will be not be used **/ public static PasswordAuthentication getPasswordAuthentication(String id, String forUrl, boolean forceRefresh, boolean hideDialogIfPasswordKnown, String i18nKey, Object... args) throws PasswortInputCanceledException { if (RapidMiner.getExecutionMode().isHeadless()) { LogService.getRoot().log(Level.WARNING, "com.rapidminer.gui.tools.PassworDialog.no_query_password_in_batch_mode", forUrl); return null; } UserCredential authentication = Wallet.getInstance().getEntry(id, forUrl); // return immediately if known and desired if (hideDialogIfPasswordKnown && !forceRefresh && (authentication != null) && (authentication.getPassword() != null)) { if (authentication.getPassword().length == 0) { return null; } LogService.getRoot().log(Level.CONFIG, "com.rapidminer.gui.tools.PassworDialog.reusing_cached_password", forUrl); return authentication.makePasswordAuthentication(); } // clear cache if refresh forced if (forceRefresh && authentication != null) { authentication.setPassword(null); Wallet.getInstance().registerCredentials(id, authentication); } if (authentication == null) { authentication = new UserCredential(forUrl, null, null); } if (i18nKey == null || i18nKey.contains("authentication")) { i18nKey = "authentication"; args = new Object[] { authentication.getURL() }; } final PasswordDialog pd = new PasswordDialog(i18nKey, authentication, args); if (SwingUtilities.isEventDispatchThread()) { pd.setVisible(true); } else { try { SwingUtilities.invokeAndWait(new Runnable() { @Override public void run() { pd.setVisible(true); } }); } catch (Exception e) { LogService.getRoot().log(Level.WARNING, "Error waiting for password authentication: " + e, e); return null; } } if (pd.wasConfirmed()) { PasswordAuthentication result = pd.makeAuthentication(); if (pd.rememberBox.isSelected()) { UserCredential userCredential = new UserCredential(forUrl, result.getUserName(), result.getPassword()); if (id != null) { Wallet.getInstance().registerCredentials(id, userCredential); } else { // compatibility with old API Wallet.getInstance().registerCredentials(userCredential); } Wallet.getInstance().saveCache(); } else { if (id != null) { Wallet.getInstance().removeEntry(id, forUrl); } else { // compatibility with old API Wallet.getInstance().removeEntry(forUrl); } Wallet.getInstance().saveCache(); } return result; } else { throw new PasswortInputCanceledException(); } } public static PasswordAuthentication getPasswordAuthentication(String forUrl, boolean forceRefresh, boolean hideDialogIfPasswordKnown) throws PasswortInputCanceledException { return getPasswordAuthentication(forUrl, forceRefresh, hideDialogIfPasswordKnown, null); } /** * @param i18nKey The i18nKey has to look like every dialog i18n: gui.dialog.KEY.title etc. * @param args Will be used when i18nKey is set. If i18nKey is <code>null</code> it will be not be used * @deprecated use {@link #getPasswordAuthentication(String, String, boolean, boolean, String, Object...)} instead. **/ @Deprecated public static PasswordAuthentication getPasswordAuthentication(String forUrl, boolean forceRefresh, boolean hideDialogIfPasswordKnown, String i18nKey, Object... args) throws PasswortInputCanceledException { return getPasswordAuthentication(null, forUrl, forceRefresh, hideDialogIfPasswordKnown, null); } }