/* * SecurityView.java * * Copyright (c) 2003-2004 Digi International * This program and the information contained in it is confidential and * proprietary to Digi International and may not be used, copied, or re- * produced without the prior written permission of Digi International. * */ package com.digi.config.ui; import com.digi.config.core.*; import com.digi.config.util.*; import javax.swing.*; import javax.swing.text.*; import java.text.*; import javax.swing.event.*; import javax.swing.tree.*; import javax.swing.border.*; import java.awt.*; import java.awt.event.*; import java.util.*; import java.io.*; import java.net.*; /** * This class is a view panel that shows serial realport * settings for the ConnectMe device * * This view can be embedded in other panels as desired. */ public class SecurityView extends ConfigViewImpl { /** A KvpNode that holds just the settings used in this view */ KvpNode viewSettingTree; /** listens to the device for changes to settings */ DeviceChangeListener settingChangeListener; /** Panel that holds the view content */ GridContentPanel content; GridContentPanel securityContent; // Data fields currently used in this view KvpField passwordModeKvpField; KvpField userNameKvpField; KvpNode passwordKvpField; // UI Controls for each filed JCheckBox passwordMode_UIC; JTextField userName_UIC; JPasswordField password_UIC; JPasswordField verifyPassword_UIC; String newPassword = ""; /** * Basic constructor. Sets up the tree view and the edit panel. */ public SecurityView() throws Exception { super(true); // create the KvpNode and the change listener viewSettingTree = new KvpNode(); settingChangeListener = new DeviceChangeListener() { public void deviceChanged(DeviceChangeEvent e) { refresh(); } }; // Create the panel that will hold the view controls content = new GridContentPanel(1); // create a listener that will detect when a user edits the field values ControlChangeAdapter fieldListener = new ControlChangeAdapter() { public void changePerformed(Object source, ActionEvent ae, FocusEvent fe) { if (source==passwordMode_UIC) { boolean pwdEnabled = passwordMode_UIC.isSelected(); passwordModeKvpField.setStringValue(stringValuePasswordMode(pwdEnabled)); securityContent.setContainerEnabled(pwdEnabled); // Keep addp in sync if (!pwdEnabled) { // Turned off password. Restore any old values and make sure we don't // send those values to the device on a save. refreshUserPassword(); } } else if (source==userName_UIC) { userNameKvpField.setStringValue(userName_UIC.getText()); } else if (source==password_UIC) { passwordKvpField.setStringValue(String.valueOf(password_UIC.getPassword())); } } }; // // Create the fields and put them on the view // passwordMode_UIC = content.addJCheckBox("SecurityPasswordMode", fieldListener); // Create the panel that will hold the security controls securityContent = new GridContentPanel(1); securityContent.addTextLine("SecurityEnabledDesc"); userName_UIC = securityContent.addJTextField("SecurityUserNameLbl", null, 150, fieldListener); userName_UIC.setDocument(createGeneralDocument()); password_UIC = securityContent.addJPasswordField("SecurityPasswordLbl", null, 150, fieldListener); password_UIC.setDocument(createGeneralDocument()); verifyPassword_UIC = securityContent.addJPasswordField("SecurityVerifyPasswordLbl", null, 150, fieldListener); verifyPassword_UIC.setDocument(createGeneralDocument()); content.addSubPanel(securityContent); content.addVGlue(); } /** * Returns a one word name identifying this view. */ public String getName() { return "SecurityView"; } /** * Return the Component that displays the primary content for this view */ public Component getViewContent() { return content; } /** * Informs view what device to work with. View should flush any * cached device data and mark current view content as invalid * so that it is refreshed appropriatly. */ public void setDevice(Device device) { super.setDevice(device); refresh(); device.addSettingChangeListener(settingChangeListener); } /** * Refreshes the local copy of the kvpGroup displayed in the view. The updated kvpGroup come * from those currently cached in the Device */ private void refresh() { viewSettingTree.clear(); // Password mode passwordModeKvpField = viewSettingTree.mergeFrom(device.getInternalSettingTree(), "simple_password", "password_mode"); passwordMode_UIC.setEnabled(passwordModeKvpField!=null); if (passwordModeKvpField!=null) { passwordMode_UIC.setSelected(booleanValuePasswordMode(passwordModeKvpField.getStringValue())); } refreshUserPassword(); } /** * Refreshes only the user/password information. */ private void refreshUserPassword() { userNameKvpField = viewSettingTree.mergeFrom(device.getInternalSettingTree(), "simple_password", "username"); userName_UIC.setEnabled(userNameKvpField!=null); if (userNameKvpField!=null) { userName_UIC.setText(userNameKvpField.getStringValue()); } // Password field isn't actually sent back from the device. KvpNode group = viewSettingTree.getGroup("simple_password"); if (group != null) { // Always clear out the password on refresh. passwordKvpField = new KvpNode("password"); group.addChild(passwordKvpField); } password_UIC.setEnabled(passwordKvpField!=null); verifyPassword_UIC.setEnabled(passwordKvpField!=null); if (passwordKvpField!=null) { password_UIC.setText(""); verifyPassword_UIC.setText(""); } securityContent.setContainerEnabled(passwordMode_UIC.isSelected()); // If no data disable entire panel if (passwordModeKvpField==null) { content.setContainerEnabled(false); } } /** * Helper to convert RCI password mode strings to boolean. * @return true if password mode enabled (test_password or always_reject), otherwise false (always_accept). */ boolean booleanValuePasswordMode(String passwordMode) { return !passwordMode.equalsIgnoreCase("always_accept"); } /** * Helper to convert boolean value of the password mode to RCI strings. * @return "test_password" if passwordModeEnabled is true or "always_accept" if passwordModeEnabled is false. */ String stringValuePasswordMode(boolean passwordModeEnabled) { if (passwordModeEnabled) { return "test_password"; } else { return "always_accept"; } } /** * This method is called to instruct the view that it is about to be made * active. When a view is active it needs to make sure its content is correct. * An example of why a panel may be inactive is if it were on a tabbed pane * and was not currently visible or if the user selected some other view. */ public void activate() { } /** * This method is called to instruct the view that it is about to be made * inactive. When a view is inactive, it does not need to worry * about maintaining its content in a correct state. An example of why a panel * may be inactive is if it were on a tabbed pane and was not currently visible * or if the user selected some other view. */ public void deactivate() { } /** * Indicates if any changes have been made by the user that have not yet been * saved to the device(ie committed). */ public boolean isChanged() { return viewSettingTree.hasChanged(); } /** * This method instructs the view to validate any of the changes the user has made * within the view. Any errors are to be added to the provided errorList. * * @param errorList is a collection of ViewValidationError objects */ public void validateChanges(Collection errorList) { // Nothing to Validate if Not Selected. if (!passwordMode_UIC.isSelected()) return; JTextComponent focusComp = null; // Set if error to set focus on a control. String password = String.valueOf(password_UIC.getPassword()); String verifyPassword = String.valueOf(verifyPassword_UIC.getPassword()); if (password.length() == 0 || password.length() > 15) { errorList.add(new ValidationError("SecurityPasswordLengthError")); focusComp = password_UIC; } else if (!password.equals(verifyPassword)) { errorList.add(new ValidationError("SecurityPasswordMismatchError")); focusComp = password_UIC; } // Trim leading/trailing spaces on user name String user = userName_UIC.getText(); user = user.trim(); userNameKvpField.setStringValue(user); // push back into field data if (user.length() == 0 || user.length() > 15) { errorList.add(new ValidationError("SecurityUserLengthError")); focusComp = userName_UIC; } if (focusComp != null) { focusComp.requestFocus(); focusComp.selectAll(); } // Save the new password for later in the commit. Unfortunately // the device object refreshes the cluster after the save, causing // our password to get reset. newPassword = password; } /** * This method instructs the view to place any changes the user has made within * the view into the provided clusters. Once the changes have been saved to * to the device, a subsequent call to commitChanges() will be made. */ public void getChanges(KvpNode settingCluster, KvpNode stateCluster) { // Merge the view changes into the provided cluster settingCluster.merge(viewSettingTree, false); } /** * Instructs the view to consider any user changes within the view as * saved to the device (ie committed). */ public void commitChanges() { boolean pwdEnabled = booleanValuePasswordMode(passwordModeKvpField.getStringValue()); if (pwdEnabled) { // Set the new credentials into the authenticator to avoid popping up // a login prompt after changing the user/password. RciAuthenticator auth = RciAuthenticator.getInstance(); auth.setNewCredentials(userNameKvpField.getStringValue(), newPassword); } // reset flags indicating user changes in the contols viewSettingTree.resetChanged(); } /** * Instructs the view to discard any changes the user has made within the * view and revert those fields to the original state. The view is also * free to refresh all its fields to the present cached state of the device at * this time. */ public void cancelChanges() { refresh(); } }