/* * ProActive Parallel Suite(TM): * The Open Source library for parallel and distributed * Workflows & Scheduling, Orchestration, Cloud Automation * and Big Data Analysis on Enterprise Grids & Clouds. * * Copyright (c) 2007 - 2017 ActiveEon * Contact: contact@activeeon.com * * This library 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: version 3 of * the License. * * 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/>. * * If needed, contact us to obtain a release under GPL Version 2 or 3 * or a different license than the AGPL. */ package org.ow2.proactive.scheduler.common; import java.awt.Rectangle; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.WindowEvent; import java.awt.event.WindowListener; import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.io.PrintWriter; import java.security.KeyException; import java.util.HashSet; import java.util.Set; import javax.security.auth.login.LoginException; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JTextField; import javax.swing.SwingConstants; import org.objectweb.proactive.annotation.PublicAPI; import org.ow2.proactive.authentication.crypto.CredData; import org.ow2.proactive.authentication.crypto.Credentials; import org.ow2.proactive.scheduler.common.exception.SchedulerException; /** * SchedulerAuthenticationHelper provides a graphical user interface to connect to the ProActiveScheduler. * <p> * Use one of the two provided method to connect the scheduler as an administrator or as a user. * This class will request username and password to the user using the graphical interface. * * @author The ProActive Team * @since ProActive Scheduling 0.9.1 */ @PublicAPI public class SchedulerAuthenticationGUIHelper { /** * Create a new instance of SchedulerAuthenticationGUIHelper. */ private SchedulerAuthenticationGUIHelper() { } /** * Connect the scheduler and return the authentication interface, username and password of the current user. * Return null if the authentication has been canceled (cancel button) or if username is not mentioned. * * @param schedulerURL the URL of the scheduler to connect * @return the authentication interface, username and password of the current user. * @throws LoginException If a problem occurs while logging the user. * @throws SchedulerException If a problem occurs at scheduler level. */ private static AuthResultContainer connect(String schedulerURL) throws LoginException, SchedulerException { AuthGraphicHelper helper = new AuthGraphicHelper(schedulerURL); helper.setVisible(true); synchronized (helper) { try { helper.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } //get selected URL schedulerURL = helper.getURL(); //join the scheduler SchedulerAuthenticationInterface auth = SchedulerConnection.join(schedulerURL); //get username and password String username = helper.getUserName(); String password = String.valueOf(helper.getPassword()); //send result if (helper.cancel || username == null || username.length() == 0) { return null; } else { return new AuthResultContainer(auth, username, password); } } /** * This method will log a client to the scheduler by requesting his URL, username and password from a * graphical interface. * * @param schedulerURL The default URL of the scheduler to connect * @return The connection to the scheduler as a {@link Scheduler} if logging successful. * If the username is empty or if the user cancel the authentication, this method will return null. * @throws LoginException If a problem occurs while logging the user. * @throws SchedulerException If a problem occurs at scheduler level. */ public static Scheduler login(String schedulerURL) throws LoginException, SchedulerException { AuthResultContainer auth = connect(schedulerURL); if (auth == null) { return null; } else { SchedulerAuthenticationInterface schedAuth = auth.getAuth(); Credentials cred = null; try { cred = Credentials.createCredentials(new CredData(CredData.parseLogin(auth.getUsername()), CredData.parseDomain(auth.getUsername()), auth.getPassword()), schedAuth.getPublicKey()); } catch (LoginException e) { throw new LoginException("Could not retrieve public key from Scheduler " + schedulerURL + ", contact the administrator" + e); } catch (KeyException e) { throw new LoginException("Could not encrypt credentials " + e); } return schedAuth.login(cred); } } static class AuthResultContainer { private SchedulerAuthenticationInterface auth; private String username; private String password; /** * Create a new instance of AuthResultContainer. * * @param auth * @param username * @param password */ public AuthResultContainer(SchedulerAuthenticationInterface auth, String username, String password) { this.auth = auth; this.username = username; this.password = password; } /** * Get the auth. * * @return the auth. */ public SchedulerAuthenticationInterface getAuth() { return auth; } /** * Get the username. * * @return the username. */ public String getUsername() { return username; } /** * Get the password. * * @return the password. */ public String getPassword() { return password; } } static class AuthGraphicHelper extends JFrame implements ActionListener, WindowListener, KeyListener { private static final String TMP_FILE_NAME = "AuthGrapHelpGUI.tmp"; private static final File TMP_AUTH_FILE = new File(System.getProperty("java.io.tmpdir") + File.separator + TMP_FILE_NAME); private JPanel jContentPane = null; private JButton jButton_OK = null; private JButton jButton_Cancel = null; private JComboBox jComboBox_url = null; private JTextField jTextField_UserName = null; private JPasswordField jPasswordField_Password = null; private JLabel jLabel_url = null; private JLabel jLabel_UserName = null; private JLabel jLabel_Password = null; private JLabel jLabel_Info = null; private boolean cancel = false; private String defaultURL = ""; private String defaultUserName = ""; private Set<String> URLs = new HashSet<>(); public void windowActivated(WindowEvent e) { } public void windowClosed(WindowEvent e) { } public void windowDeactivated(WindowEvent e) { } public void windowDeiconified(WindowEvent e) { } public void windowIconified(WindowEvent e) { } public void windowOpened(WindowEvent e) { } public void keyReleased(KeyEvent e) { } public void keyTyped(KeyEvent e) { } /** * This is the default constructor */ private AuthGraphicHelper() { super(); initialize(); } /** * This is an other constructor that is build with default URL */ private AuthGraphicHelper(String defaultURL) { super(); this.defaultURL = defaultURL; initialize(); } /** * This is an other constructor that is build with default URL and UserName */ private AuthGraphicHelper(String defaultURL, String defaultUserName) { super(); this.defaultURL = defaultURL; this.defaultUserName = defaultUserName; initialize(); } /** * This method initializes this * * @return void */ private void initialize() { loadURLs(); int thisH = 200; int thisW = 450; this.setSize(thisW, thisH); this.setContentPane(getJContentPane()); this.setTitle("ProActive Scheduler Authentication"); this.setResizable(false); this.setAlwaysOnTop(true); this.addWindowListener(this); int h = Toolkit.getDefaultToolkit().getScreenSize().height; int w = Toolkit.getDefaultToolkit().getScreenSize().width; this.setLocation((w - thisW) / 2, (h - thisH) / 2); } /** * This method initializes jButton_OK * * @return javax.swing.JButton */ private JButton getJButton_OK() { if (jButton_OK == null) { jButton_OK = new JButton(); jButton_OK.setBounds(new Rectangle(85, 136, 100, 22)); jButton_OK.setText("OK"); jButton_OK.addActionListener(this); jButton_OK.setActionCommand("JButton_OK"); jButton_OK.addKeyListener(this); } return jButton_OK; } /** * This method initializes jButton_Cancel * * @return javax.swing.JButton */ private JButton getJButton_Cancel() { if (jButton_Cancel == null) { jButton_Cancel = new JButton(); jButton_Cancel.setBounds(new Rectangle(260, 136, 100, 22)); jButton_Cancel.setText("Cancel"); jButton_Cancel.addActionListener(this); jButton_Cancel.setActionCommand("JButton_Cancel"); jButton_Cancel.addKeyListener(this); } return jButton_Cancel; } /** * This method initializes JComboBox_url * * @return javax.swing.getJComboBox */ private JComboBox getJComboBox_url() { if (jComboBox_url == null) { jComboBox_url = new JComboBox(); jComboBox_url.setBounds(new Rectangle(130, 40, 300, 22)); for (String s : URLs) { jComboBox_url.addItem(s); } if (!"".equals(defaultURL)) { jComboBox_url.setSelectedItem(defaultURL); } jComboBox_url.setEditable(true); jComboBox_url.addKeyListener(this); } return jComboBox_url; } /** * Get the URL as it has been set * * @return the URL as it has been set */ public String getURL() { return (String) jComboBox_url.getSelectedItem(); } /** * This method initializes jTextField_UserName * * @return javax.swing.JTextField */ private JTextField getJTextField_UserName() { if (jTextField_UserName == null) { jTextField_UserName = new JTextField(); jTextField_UserName.setBounds(new Rectangle(130, 70, 300, 22)); jTextField_UserName.setText(defaultUserName); jTextField_UserName.addKeyListener(this); } return jTextField_UserName; } /** * Get the userName as it has been set * * @return the userName as it has been set */ public String getUserName() { return jTextField_UserName.getText(); } /** * This method initializes jPasswordField_Password * * @return javax.swing.JPasswordField */ private JPasswordField getJPasswordField_Password() { if (jPasswordField_Password == null) { jPasswordField_Password = new JPasswordField(); jPasswordField_Password.setBounds(new Rectangle(130, 100, 300, 22)); jPasswordField_Password.addKeyListener(this); } return jPasswordField_Password; } /** * Get the password as it has been set * * @return the password as it has been set */ public char[] getPassword() { return jPasswordField_Password.getPassword(); } /** * This method initializes jContentPane * * @return javax.swing.JPanel */ private JPanel getJContentPane() { if (jContentPane == null) { jLabel_Info = new JLabel(); jLabel_Info.setBounds(new Rectangle(12, 10, 380, 22)); jLabel_Info.setHorizontalAlignment(SwingConstants.LEFT); jLabel_Info.setText("Identification required to connect the Scheduler :"); jLabel_url = new JLabel(); jLabel_url.setBounds(new Rectangle(12, 40, 90, 22)); jLabel_url.setHorizontalAlignment(SwingConstants.RIGHT); jLabel_url.setText("URL : "); jLabel_UserName = new JLabel(); jLabel_UserName.setBounds(new Rectangle(12, 70, 90, 22)); jLabel_UserName.setHorizontalAlignment(SwingConstants.RIGHT); jLabel_UserName.setText("Username : "); jLabel_Password = new JLabel(); jLabel_Password.setBounds(new Rectangle(12, 100, 90, 22)); jLabel_Password.setHorizontalAlignment(SwingConstants.RIGHT); jLabel_Password.setText("Password : "); jContentPane = new JPanel(); jContentPane.setLayout(null); jContentPane.add(getJButton_OK(), null); jContentPane.add(getJButton_Cancel(), null); jContentPane.add(getJComboBox_url(), null); jContentPane.add(getJTextField_UserName(), null); jContentPane.add(getJPasswordField_Password(), null); jContentPane.add(jLabel_UserName, null); jContentPane.add(jLabel_Password, null); jContentPane.add(jLabel_Info, null); jContentPane.add(jLabel_url, null); } return jContentPane; } /** * Terminate this authentication panel by closing it and unlock awaiting threads */ private void terminate() { saveURLs(); this.setVisible(false); synchronized (this) { this.notifyAll(); } this.dispose(); } /** * Return true if the form has been canceled. * * @return true if the form has been canceled, false otherwise. */ public boolean hasBeenCanceled() { return this.cancel; } /** * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent) */ public void actionPerformed(ActionEvent arg0) { if (arg0.getActionCommand().equals(jButton_Cancel.getActionCommand())) { this.cancel = true; } terminate(); } /** * @see java.awt.event.WindowListener#windowClosing(java.awt.event.WindowEvent) */ public void windowClosing(WindowEvent e) { this.cancel = true; terminate(); } /** * @see java.awt.event.KeyListener#keyPressed(java.awt.event.KeyEvent) */ public void keyPressed(KeyEvent e) { if (e.getSource() == this.jButton_Cancel && e.getKeyCode() == KeyEvent.VK_ENTER) { this.cancel = true; terminate(); } if (e.getKeyCode() == KeyEvent.VK_ENTER) { terminate(); } } private void saveURLs() { if (!"".equals((String) jComboBox_url.getSelectedItem())) { URLs.add((String) jComboBox_url.getSelectedItem()); } PrintWriter pw = null; try { pw = new PrintWriter(new FileOutputStream(TMP_AUTH_FILE)); for (String url : URLs) { pw.println(url); } } catch (Exception e) { //not a big deal } finally { if (pw != null) { pw.close(); } } } private void loadURLs() { if (!"".equals(defaultURL)) { URLs.add(defaultURL); } BufferedReader br = null; try { br = new BufferedReader(new FileReader(TMP_AUTH_FILE)); String url; while ((url = br.readLine()) != null) { if (!"".equals(url)) { URLs.add(url); } } } catch (Exception e) { //If file not found, it will be created after //if other, we cannot read historic -> not a big deal } finally { if (br != null) { try { br.close(); } catch (IOException e) { } } } } } }