package gui.intro; import java.awt.Color; import java.awt.Component; import java.awt.Image; import java.awt.SystemColor; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.concurrent.ExecutionException; import javax.swing.ButtonGroup; import javax.swing.DefaultComboBoxModel; import javax.swing.DefaultListCellRenderer; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JInternalFrame; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JRadioButton; import javax.swing.JTextField; import javax.swing.SwingConstants; import javax.swing.SwingWorker; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; import javax.swing.border.EmptyBorder; import javax.swing.border.TitledBorder; import models.SessionData; import models.person; import org.apache.log4j.Logger; import org.apache.thrift.TException; import org.openslx.imagemaster.thrift.iface.ImageServer; import org.openslx.imagemaster.thrift.iface.OrganizationData; import org.openslx.imagemaster.thrift.iface.UserInfo; import org.openslx.thrifthelper.ThriftManager; import util.GuiManager; import util.ResourceLoader; import util.ShibbolethECP; import config.Config; @SuppressWarnings("serial") public class Login_GUI extends JInternalFrame { /** * Logger instance for this class. */ private final static Logger LOGGER = Logger.getLogger(Login_GUI.class); String authToken = null; // String constants representing the different login methods private final static String LOGIN_TYPE_BWIDM = "bwidm"; private final static String LOGIN_TYPE_BWLEHRPOOL = "bwlp"; private final static String LOGIN_TYPE_SATELLITE = "sat"; private JPanel contentPane; private JTextField lblusername; private JPasswordField lblpass; JLabel lblConnectionInfo = new JLabel(""); boolean isClientReturnedCorrectly = false; JCheckBox chckbxBenutzernameSpeichern; Component c = null; private JPanel panel; private JPanel panel_1; private JLabel LabelUser; private JLabel LabelPass; // radio button and group for login types. private ButtonGroup bgLoginType; private JRadioButton rdbtnBwIDM; private JRadioButton rdbtnDirekteVerbindung; private JRadioButton rdbtnMasterserver; // its action listener private ActionListener loginTypeActionListener; // bwIDM label and dropdown private JComboBox idpChoice; private JLabel lblIdp; private List organizations; // Satellite IP label and text field private JLabel lblSatellitenIp; private JTextField lblSatIP; /** * Create the frame. */ public Login_GUI() { try { // Setzt das Look and Feel auf System UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) { e.printStackTrace(); } // Titel des Fensters setzen setTitle("bwLehrpool Suite"); // Größe setzen und mittig ausrichten setBounds(0, 0, 785, 430); // Erzeugen eines Panels contentPane = new JPanel(); // Hintergrund Farbe des Panels setzen contentPane.setBackground(SystemColor.menu); // Rahmen des Fensters setzen contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); setContentPane(contentPane); // Layout setzen contentPane.setLayout(null); // Label fuer das Logo erzeugen JLabel imgLabel = new JLabel(); // Groesse und Position des Logos festelegen imgLabel.setBounds(231, 11, 350, 142); // Pfadangabe des Logos ImageIcon icon = ResourceLoader.getIcon("/img/Logo_bwLehrpool.png", "Logo"); // Skalierung des Logos Image scaled = icon.getImage().getScaledInstance(270, 64, 0); imgLabel.setIcon(new ImageIcon(scaled)); // Hinzufuegen des Logos in das Fenster contentPane.add(imgLabel); lblConnectionInfo.setHorizontalAlignment(SwingConstants.LEFT); lblConnectionInfo.setBounds(10, 359, 449, 20); lblConnectionInfo.setEnabled(true); lblConnectionInfo.setText("Info: Bereit für Login"); contentPane.add(lblConnectionInfo); // Erzeugen, Hinzufuegen und definierung der Aktion des Buttons JButton BtnLogin = new JButton("Login"); BtnLogin.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { performLogin(bgLoginType.getSelection().getActionCommand()); }// end actionPerformed }); BtnLogin.setBounds(488, 358, 239, 23); contentPane.add(BtnLogin); // Start of the actual content of the right panel panel = new JPanel(); panel.setLayout(null); panel.setBorder(new TitledBorder(null, "Zugangsdaten", TitledBorder.LEADING, TitledBorder.TOP, null, null)); panel.setBackground(SystemColor.menu); panel.setBounds(354, 143, 400, 181); contentPane.add(panel); chckbxBenutzernameSpeichern = new JCheckBox("Benutzername speichern"); chckbxBenutzernameSpeichern.setBounds(135, 137, 237, 23); chckbxBenutzernameSpeichern.setSelected(Config.getSaveUsername()); panel.add(chckbxBenutzernameSpeichern); // Erzeugen und Hinzufuegen des Labels LabelUser = new JLabel("Benutzername:"); LabelUser.setBounds(25, 60, 82, 20); panel.add(LabelUser); // Erzeugen und Hinzufuegen des Textfeldes lblusername = new JTextField(); lblusername.setBounds(135, 60, 237, 20); lblusername.setToolTipText("Bitte geben Sie Ihren bwIDM-Benutzernamen ein."); lblusername.setColumns(10); // Lese Benutzername aus der Konfigurationsdatei lblusername.setText(Config.getUsername()); lblusername.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { performLogin(bgLoginType.getSelection().getActionCommand()); } }); panel.add(lblusername); // Erzeugen und Hinzufuegen des Labels LabelPass = new JLabel("Passwort:"); LabelPass.setBounds(25, 85, 82, 20); panel.add(LabelPass); // Erzeugen und Hinzufuegen des Passwortfeldes lblpass = new JPasswordField(); lblpass.setBounds(135, 85, 237, 20); lblpass.setToolTipText("Bitte geben Sie Ihr bwIDM-Passwort ein."); lblpass.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { performLogin(bgLoginType.getSelection().getActionCommand()); } }); panel.add(lblpass); lblSatellitenIp = new JLabel("Satelliten IP:"); lblSatellitenIp.setBounds(25, 105, 82, 20); //panel.add(lblSatellitenIp); lblSatIP = new JTextField(); lblSatIP.setBounds(135, 110, 237, 20); lblSatIP.setToolTipText("Bitte geben Sie die IP-Adresse des Satelliten ein."); //panel.add(lblSatIP); idpChoice = new JComboBox(); idpChoice.setBounds(135, 35, 237, 20); //panel.add(choice); lblIdp = new JLabel("IdP:"); lblIdp.setBounds(25, 35, 82, 20); //panel.add(lblIdp); // action listener for the radio buttons to // toggle the gui elements depending on the login type loginTypeActionListener = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { toggleLoginType(e.getActionCommand()); } }; panel_1 = new JPanel(); panel_1.setLayout(null); panel_1.setBorder(new TitledBorder( UIManager.getBorder("TitledBorder.border"), "Authentifizierungsart", TitledBorder.LEADING, TitledBorder.TOP, null, new Color(0, 0, 0))); panel_1.setBackground(SystemColor.menu); panel_1.setBounds(10, 143, 334, 181); contentPane.add(panel_1); // group radio button for the login type together bgLoginType = new ButtonGroup(); rdbtnBwIDM = new JRadioButton("Authentifizierung über bwIDM"); rdbtnBwIDM.setBounds(32, 35, 244, 23); rdbtnBwIDM.setActionCommand(LOGIN_TYPE_BWIDM); rdbtnBwIDM.addActionListener(loginTypeActionListener); bgLoginType.add(rdbtnBwIDM); panel_1.add(rdbtnBwIDM); rdbtnMasterserver = new JRadioButton("Test-Zugang mit festem Benutzer"); rdbtnMasterserver.setSelected(true); rdbtnMasterserver.setActionCommand(LOGIN_TYPE_BWLEHRPOOL); rdbtnMasterserver.addActionListener(loginTypeActionListener); rdbtnMasterserver.setBounds(32, 60, 244, 23); bgLoginType.add(rdbtnMasterserver); panel_1.add(rdbtnMasterserver); rdbtnDirekteVerbindung = new JRadioButton("Direkte Verbindung zum Satelliten"); rdbtnDirekteVerbindung.setBounds(32, 85, 244, 23); rdbtnDirekteVerbindung.setActionCommand(LOGIN_TYPE_SATELLITE); rdbtnDirekteVerbindung.addActionListener(loginTypeActionListener); rdbtnDirekteVerbindung.setEnabled(false); bgLoginType.add(rdbtnDirekteVerbindung); panel_1.add(rdbtnDirekteVerbindung); panel.setVisible(true); panel_1.setVisible(true); contentPane.setVisible(true); }// end LoginGUI() // Versuche den Benutzer einzuloggen public void performLogin(final String loginType) { LOGGER.info("Trying login of type: " + loginType); if (loginType == LOGIN_TYPE_BWLEHRPOOL) { // start the authentication process against the masterserver org.openslx.imagemaster.thrift.iface.SessionData result = null; // Connect to Master ImageServer.Iface client = ThriftManager.getMasterClient(); String passText = new String(lblpass.getPassword()); UserInfo user = null; // Log user in try { setStatus(Color.black, "Authentifiziere - warte auf Antwort von Server...", null); result = client.authenticate(lblusername.getText(), passText); // Sanity checks if (result.authToken == null || result.sessionId == null) { setStatus(Color.red, "Antwort des Masterservers korrupt.", null); LOGGER.info("Antwort des Masterservers korrupt"); return; } // User-Info LOGGER.info("Authentifizierung von '" + lblusername.getText() + "' erfolgreich."); user = client.getUserFromToken(result.authToken); authToken = result.authToken; } catch (org.openslx.imagemaster.thrift.iface.AuthenticationException e) { setStatus( Color.red, "Fehler: Zugangsdaten nicht akzeptiert.", "Benutzeranmeldung fehlgeschlagen: Bitte Benutzername und Passwort überprüfen.\n" + e.message); e.printStackTrace(); return; } catch (TException e) { e.printStackTrace(); setStatus(Color.red, "Kommunikation mit Masterserver fehlgeschlagen.", null); LOGGER.error("Thrift-communication to the masterserver failed, see trace: ", e); return; } // set Information SessionData.session.setAuthToken(result.authToken); SessionData.session.setSessionID(result.sessionId); SessionData.session.setServerAdress(result.serverAddress); if (!ThriftManager.setSatellite(result.serverAddress)) { LOGGER.error("Setting satellite IP to '" + result.serverAddress + "' failed. Appears to be empty. Is the satellite IP returned from masterserver correct?"); setStatus(Color.green, "IP von Satelliten invalid.", null); System.exit(1); // TODO handle this correctly } // Satellite-Connection setStatus(Color.black, "Hole Verbindungsdaten von Server...", null); // User-Info setStatus(Color.green, "Daten erhalten.", null); String hochschule = user.eMail.substring(user.eMail.indexOf("@") + 1); person.verantwortlicher.setUsername(lblusername.getText().trim()); person.verantwortlicher.setUserID(lblusername.getText().trim()); person.verantwortlicher.setName(user.lastName); person.verantwortlicher.setVorname(user.firstName); person.verantwortlicher.setEMail(user.eMail); person.verantwortlicher.setHochschule(hochschule); // Spaeter ueber result.getRole zum Beispiel die Rolle holen if(lblusername.getText().trim().startsWith("admin@")){ person.verantwortlicher.setRole("Admin"); } else { person.verantwortlicher.setRole("Dozent"); //person.verantwortlicher.setRole("Student"); } postLogin(); //} } // end bwLehrpool-Login if (loginType == LOGIN_TYPE_BWIDM) { // try the shibbo login in its own SwingWorker to avoid GUI lockups SwingWorker worker = new SwingWorker(){ @Override protected ShibbolethECP.ReturnCode doInBackground() throws Exception { publish("Info: Initialisiere Shibboleth-Client ..."); OrganizationData selectedOrg = (OrganizationData) idpChoice.getSelectedItem(); publish("Info: Überprüfe Zugangdaten über bwIDM ..."); return ShibbolethECP.doLogin(selectedOrg.getEcpUrl(), lblusername.getText().trim(), String.valueOf(lblpass.getPassword())); } protected void done() { try { ShibbolethECP.ReturnCode ecpReturn = get(); switch(ecpReturn) { case NO_ERROR: setStatus(Color.green, "Info: bwIDM-Anmeldung erfolgreich.", null); /* * Login successful */ person.verantwortlicher.setUsername(lblusername.getText().trim()); person.verantwortlicher.setUserID(lblusername.getText().trim()); person.verantwortlicher.setName(ShibbolethECP.getResponse().lastName); person.verantwortlicher.setVorname(ShibbolethECP.getResponse().firstName); person.verantwortlicher.setEMail(ShibbolethECP.getResponse().mail); person.verantwortlicher.setHochschule(((OrganizationData)idpChoice.getSelectedItem()).getOrganizationId()); person.verantwortlicher.setRole("Dozent"); authToken = ShibbolethECP.getResponse().token; ThriftManager.setSatellite(ShibbolethECP.getResponse().satellites.get("default")); SessionData.session.setServerAdress(ShibbolethECP.getResponse().satellites.get("default")); SessionData.session.setAuthToken(ShibbolethECP.getResponse().token); SessionData.session.setSessionID(ShibbolethECP.getResponse().sessionId); /* * Now postprocess successful login */ postLogin(); //showMainMenu(); break; case ERROR_IDP: setStatus(Color.red, "Fehler: bwIDM-Anmeldung fehlgeschlagen!", null); JOptionPane.showMessageDialog(c, "Anmeldung fehlgeschlagen. Überprüfen Sie den Benutzername und Passwort.", "Fehler", JOptionPane.ERROR_MESSAGE); break; case ERROR_UNREG: setStatus(Color.red, "Fehler: Nicht bei bwLehrpool registriert!", null); JOptionPane.showMessageDialog(c, "Sie sind nicht bei bwLehrpool registriert.\nGehen Sie dazu auf folgende Seite:\n" + ShibbolethECP.getRegistrationUrl(), "Fehler", JOptionPane.ERROR_MESSAGE); break; case ERROR_SP: setStatus(Color.red, "Fehler: bwIDM-Anmeldung fehlgeschlagen!", null); JOptionPane.showMessageDialog(c, "Anmeldung erfolgreich aber die Antwort des Service Providers ist ungültig.", "Fehler", JOptionPane.ERROR_MESSAGE); break; case ERROR_OTHER: setStatus(Color.red, "Fehler: bwIDM-Anmeldung fehlgeschlagen!", null); JOptionPane.showMessageDialog(c, "Fataler Fehler. Schicken Sie die Log-Datei einem Administrator zu!", "Fehler", JOptionPane.ERROR_MESSAGE); break; default: setStatus(Color.red, "Fehler: bwIDM-Login fehlgeschlagen!", null); } } catch (InterruptedException e) { LOGGER.error("SwingWorker for ShibbolethECP got interrupted, see trace: ", e); } catch (ExecutionException e) { LOGGER.error("Execution of SwingWorker for ShibbolethECP failed, see trace: ", e); } } @Override protected void process(List msgs) { String currentMessage = msgs.get(msgs.size()-1); setStatus(Color.black, currentMessage, null); } }; worker.execute(); } // always save to user's config file. if (chckbxBenutzernameSpeichern.isSelected()) { Config.setUsername(lblusername.getText()); Config.setSaveUsername(true); } else { Config.setUsername(""); Config.setSaveUsername(false); } // save it to local disk Config.store(); }// end performLogin /** * Common function for either authentication method */ private void postLogin() { LOGGER.debug("Post-processing login ..."); // TODO here do all the session data stuff // TODO and the telling the sat Server who we are LOGGER.debug("Checking token: " + SessionData.session.getAuthToken()); try { boolean authenticated = ThriftManager.getSatClient().authenticated(SessionData.session.getAuthToken()); if(!authenticated) { //TODO message for user and deactivation of menu points, actually just system exit System.exit(0); } } catch (TException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } try { String pk_institution = ThriftManager.getSatClient().setInstitution(person.verantwortlicher.getHochschule(),SessionData.session.getAuthToken()); ThriftManager.getSatClient().setPerson(person.verantwortlicher.getUserID(),SessionData.session.getAuthToken(),pk_institution); } catch (TException e) { // TODO Auto-generated catch block e.printStackTrace(); } // at the end showMainMenu(); } /** * Shows the next GUI's til the main menu. * It checks if the user has already seen the bill of rights * and/or the vmware license windows and shows them before * continuing to the main menu. * * This function should be called on a successful login. */ private void showMainMenu() { /** * * DISPLAY LICENSES / MAIN MENU * */ if (!Config.getBillOfRights()) { // display bill of rights? GuiManager.show(new BillOfRights_GUI(), true); } else { // display vmware license? if (!Config.getVmwareLicense()) { GuiManager.show(new VmWareLink_GUI(), true); } else { // main menu GuiManager.show(new MainMenue_GUI(), true); } } } /** * Set connection status message, optionally show message box. * * @param color * Color to display status message in. * @param shortMessage * The message to display. * @param longMessage * Optional message to show in a message box. null means don't * show. */ private void setStatus(Color color, String shortMessage, String longMessage) { LOGGER.info(shortMessage); lblConnectionInfo.setForeground(color); lblConnectionInfo.setText(shortMessage); if (longMessage != null) JOptionPane.showMessageDialog(c, longMessage, "Anmeldung fehlgeschlagen", JOptionPane.ERROR_MESSAGE); } /** * Toggle the elements needed for the different login types. * * @param type * Type of the login to toggle. Valid are: * - LOGIN_TYPE_BWIDM * - LOGIN_TYPE_BWLEHRPOOL * - LOGIN_TYPE_SATELLITE */ private void toggleLoginType(String type) { LOGGER.info("Toggling to login method to: " + type); panel.setVisible(false); switch(type) { case LOGIN_TYPE_BWIDM: initIdpList(); panel.remove(lblSatIP); panel.remove(lblSatellitenIp); panel.add(idpChoice); panel.add(lblIdp); panel.add(LabelPass); lblpass.setText(""); lblpass.setToolTipText("Bitte geben Sie Ihr bwIDM-Passwort ein."); panel.add(lblpass); lblusername.setToolTipText("Bitte geben Sie Ihr bwIDM-Benutzername ein."); panel.revalidate(); panel.repaint(); panel.setVisible(true); break; case LOGIN_TYPE_BWLEHRPOOL: panel.remove(idpChoice); panel.remove(lblIdp); panel.remove(lblSatIP); panel.remove(lblSatellitenIp); panel.add(LabelPass); lblpass.setToolTipText("Bitte geben Sie Ihr bwLehrpool-Passwort ein."); panel.add(lblpass); lblusername.setToolTipText("Bitte geben Sie Ihr bwLehrpool-Benutzername ein."); panel.revalidate(); panel.repaint(); panel.setVisible(true); break; case LOGIN_TYPE_SATELLITE: panel.remove(idpChoice); panel.remove(lblIdp); panel.remove(LabelPass); panel.remove(lblpass); lblSatIP.setBounds(135, 85, 237, 20); lblSatIP.setText(""); panel.add(lblSatIP); lblSatellitenIp.setBounds(25, 85, 82, 20); panel.add(lblSatellitenIp); panel.revalidate(); panel.repaint(); panel.setVisible(true); setStatus(Color.black, "Info: Bereit für bwIDM-Login", null); break; default: panel.setVisible(true); return; } } /** * Request the list of identity providers from the masterserver and * display them in a combobox. */ private void initIdpList() { // abort if we fetched the list already. if (organizations != null) { return; } else { organizations = new ArrayList(); } LOGGER.info("Fetching list of identity providers from masterserver..."); SwingWorker worker = new SwingWorker(){ @Override protected Boolean doInBackground() throws Exception { publish("Info: Hole Liste von IdPs"); // if not then request it from the masterserver List tempOrgs = null; try { tempOrgs = ThriftManager.getMasterClient().getOrganizations(); } catch (TException e) { LOGGER.error("Could not fetch list of identity providers from the masterserver, see trace: ", e); return false; } // safety check to see if we got any organizations at all if (tempOrgs != null) { // now add those with an Ecp URL to the result list. for (OrganizationData org : tempOrgs) { if (org.getEcpUrl() != null && !org.getEcpUrl().isEmpty()) { organizations.add(org); LOGGER.debug("Valid IdP: " + org.toString()); } else { LOGGER.debug("Skipped bad organization (no ECPUrl): " + org.toString()); } } // now we build the list, lets sort it Collections.sort(organizations, new Comparator() { @Override public int compare(OrganizationData o1, OrganizationData o2) { return o1.displayName.compareTo(o2.displayName); } }); } else { LOGGER.error("Thrift call of 'getOrganizations()' seems to have worked, but 'organizations' is still null."); LOGGER.error("Is the API of the masterserver working correctly?"); return false; } publish("Info: Liste von IdPs empfangen."); return true; } protected void done() { try { if (get()) { // fill the combobox with the IdPs returned from the masterserver OrganizationData[] orgs = organizations.toArray(new OrganizationData[]{}); idpChoice.setModel(new DefaultComboBoxModel(orgs)); // now override the renderer, to show the display names of the organizations. idpChoice.setRenderer(new DefaultListCellRenderer() { @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); if (value instanceof OrganizationData){ OrganizationData org = (OrganizationData) value; setText(org.getDisplayName()); } return this; } }); setStatus(Color.black, "Info: Bereit für Login", null); } else { setStatus(Color.red, "Fehler: Vorbereitung für bwIDM-Login fehlgeschlagen!", null); } } catch (InterruptedException e) { LOGGER.error("SwingWorker for 'getOrganizationsList' got interrupted, see trace: ", e); } catch (ExecutionException e) { LOGGER.error("Execution of SwingWorker for 'getOrganizationsList' failed, see trace: ", e); } } @Override protected void process(List msgs) { String currentMessage = msgs.get(msgs.size()-1); setStatus(Color.black, currentMessage, null); } }; worker.execute(); } }// end class