/**
* Aptana Studio
* Copyright (c) 2005-2011 by Appcelerator, Inc. All Rights Reserved.
* Licensed under the terms of the GNU Public License (GPL) v3 (with exceptions).
* Please see the license.html included with this distribution for details.
* Any modifications to this file must keep this entire header intact.
*/
// $codepro.audit.disable variableDeclaredInLoop
package com.aptana.ui.secureftp.internal;
import java.io.File;
import java.util.Arrays;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.layout.LayoutConstants;
import org.eclipse.jface.layout.PixelConverter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import com.aptana.core.logging.IdeLog;
import com.aptana.core.util.StringUtil;
import com.aptana.filesystem.ftp.IBaseFTPConnectionPoint;
import com.aptana.filesystem.ftp.Policy;
import com.aptana.filesystem.secureftp.IFTPSConnectionPoint;
import com.aptana.filesystem.secureftp.ISFTPConnectionPoint;
import com.aptana.filesystem.secureftp.SFTPConnectionPoint;
import com.aptana.filesystem.secureftp.SecureUtils;
import com.aptana.ide.core.io.ConnectionPointType;
import com.aptana.ide.core.io.CoreIOPlugin;
import com.aptana.ide.core.io.IBaseRemoteConnectionPoint;
import com.aptana.ide.ui.io.dialogs.IDialogConstants;
import com.aptana.ui.ftp.internal.FTPAdvancedOptionsComposite;
import com.aptana.ui.ftp.internal.FTPConnectionPropertyComposite;
import com.aptana.ui.ftp.internal.IOptionsComposite;
import com.aptana.ui.secureftp.SecureFTPUIPlugin;
import com.aptana.ui.secureftp.dialogs.Messages;
import com.aptana.ui.util.UIUtils;
/**
*
* @author Max Stepanov
*
*/
public class CommonFTPConnectionPropertyComposite extends FTPConnectionPropertyComposite
{
private static final ConnectionPointType[] PROTOCOL_TYPES = new ConnectionPointType[] {
CoreIOPlugin.getConnectionPointManager().getType(IBaseFTPConnectionPoint.TYPE_FTP),
CoreIOPlugin.getConnectionPointManager().getType(IFTPSConnectionPoint.TYPE_FTPS),
CoreIOPlugin.getConnectionPointManager().getType(ISFTPConnectionPoint.TYPE_SFTP) };
private Combo protocolButton;
private Composite keyAuthComposite;
private Button keyAuthButton;
private Label keyPathLabel;
private Composite[] advancedOptionsComposites;
private ConnectionPointType connectionType;
private IListener listener;
public CommonFTPConnectionPropertyComposite(Composite parent, int style,
IBaseRemoteConnectionPoint connectionPoint, IListener listener)
{
super(parent, style, connectionPoint, listener);
this.listener = listener;
}
@Override
public ConnectionPointType getConnectionPointType()
{
if (connectionType != null)
{
return connectionType;
}
return super.getConnectionPointType();
}
public void setConnectionPointType(ConnectionPointType type)
{
changeProtocolType(type);
}
@Override
public void setConnectionPoint(IBaseRemoteConnectionPoint connectionPoint)
{
super.setConnectionPoint(connectionPoint);
if (ftpConnectionPoint != null)
{
setConnectionPointType(CoreIOPlugin.getConnectionPointManager().getType(ftpConnectionPoint));
}
}
@Override
public boolean isValid()
{
if (!super.isValid())
{
return false;
}
String message = null;
if (keyAuthButton.getSelection())
{
IPath keyFilePath = Path.fromPortableString(keyPathLabel.getText());
try
{
boolean passphraseProtected = SecureUtils.isKeyPassphraseProtected(keyFilePath.toFile());
char[] password = passwordText.getText().toCharArray();
if (passphraseProtected && password.length > 0)
{
if (!SecureUtils.isPassphraseValid(keyFilePath.toFile(), password))
{
message = Messages.CommonFTPConnectionPointPropertyDialog_IncorrectPassphrase;
}
}
}
catch (CoreException e)
{
message = e.getLocalizedMessage();
}
}
listener.error(message);
return message == null;
}
@Override
protected void createSiteSection(Composite parent)
{
super.createSiteSection(parent);
Label label = new Label(parent, SWT.NONE);
label.setLayoutData(GridDataFactory.swtDefaults().hint(
new PixelConverter(label).convertHorizontalDLUsToPixels(IDialogConstants.LABEL_WIDTH), SWT.DEFAULT)
.create());
label.setText(StringUtil.makeFormLabel(Messages.CommonFTPConnectionPointPropertyDialog_Protocol));
protocolButton = new Combo(parent, SWT.READ_ONLY | SWT.DROP_DOWN);
String[] items = new String[PROTOCOL_TYPES.length];
for (int i = 0; i < items.length; ++i)
{
items[i] = PROTOCOL_TYPES[i].getName();
}
protocolButton.setItems(items);
updateProtocolButton();
protocolButton.setLayoutData(GridDataFactory.swtDefaults().hint(
Math.max(new PixelConverter(protocolButton)
.convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH), protocolButton.computeSize(
SWT.DEFAULT, SWT.DEFAULT, true).x), SWT.DEFAULT).create());
/* -- */
protocolButton.addSelectionListener(new SelectionAdapter()
{
@Override
public void widgetSelected(SelectionEvent e)
{
changeProtocolType(PROTOCOL_TYPES[protocolButton.getSelectionIndex()]);
}
});
}
@Override
protected void createPasswordSection(Composite parent)
{
keyAuthComposite = new Composite(parent, SWT.NONE);
keyAuthComposite.setLayoutData(GridDataFactory.fillDefaults().span(3, 1).grab(true, false).create());
makeVisible(keyAuthComposite, false);
keyAuthComposite.setLayout(GridLayoutFactory.fillDefaults().spacing(LayoutConstants.getSpacing().x, 0)
.numColumns(2).create());
/* row 1 */
Label label = new Label(keyAuthComposite, SWT.NONE);
label.setLayoutData(GridDataFactory.swtDefaults().hint(
new PixelConverter(label).convertHorizontalDLUsToPixels(IDialogConstants.LABEL_WIDTH), SWT.DEFAULT)
.create());
keyAuthButton = new Button(keyAuthComposite, SWT.CHECK);
keyAuthButton.setLayoutData(GridDataFactory.fillDefaults().create());
keyAuthButton.setText(Messages.CommonFTPConnectionPointPropertyDialog_UsePublicKeyAuthentication);
/* row 2 */
label = new Label(keyAuthComposite, SWT.NONE);
label.setLayoutData(GridDataFactory.swtDefaults().hint(
new PixelConverter(label).convertHorizontalDLUsToPixels(IDialogConstants.LABEL_WIDTH), SWT.DEFAULT)
.create());
keyPathLabel = new Label(keyAuthComposite, SWT.NONE);
keyPathLabel.setLayoutData(GridDataFactory.fillDefaults().create());
keyPathLabel.setFont(smallFont);
keyPathLabel.setText(Messages.CommonFTPConnectionPointPropertyDialog_NoPrivateKeySelected);
super.createPasswordSection(parent);
updateKeyAuth();
/* -- */
keyAuthButton.addSelectionListener(new SelectionAdapter()
{
@Override
public void widgetSelected(SelectionEvent e)
{
changeKeyAuthentication();
validate();
}
});
}
@Override
protected void createAdvancedOptions(Composite parent)
{
advancedOptionsComposites = new Composite[] { new FTPAdvancedOptionsComposite(parent, SWT.NONE, this),
new FTPSAdvancedOptionsComposite(parent, SWT.NONE, this),
new SFTPAdvancedOptionsComposite(parent, SWT.NONE, this) };
for (Composite composite : advancedOptionsComposites)
{
composite.setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create());
makeVisible(composite, false);
}
updateAdvancedOptions();
}
@Override
protected String getAuthId(IBaseRemoteConnectionPoint connectionPoint)
{
if (ISFTPConnectionPoint.TYPE_SFTP.equals(getConnectionPointType().getType()))
{
if (keyAuthButton.getSelection())
{
return Policy.generateAuthId(
getConnectionPointType().getType().toUpperCase() + "/PUBLICKEY", connectionPoint);} //$NON-NLS-1$
}
return super.getAuthId(connectionPoint);
}
@Override
protected void loadPropertiesFrom(IBaseRemoteConnectionPoint connectionPoint)
{
if (connectionPoint instanceof SFTPConnectionPoint)
{
SFTPConnectionPoint sftpConnectionPoint = (SFTPConnectionPoint) connectionPoint;
IPath keyFilePath = sftpConnectionPoint.getKeyFilePath();
makeVisible(passwordLabel, true);
makeVisible(passwordText, true);
makeVisible(savePasswordButton, true);
if (keyFilePath != null && !keyFilePath.isEmpty())
{
keyAuthButton.setSelection(true);
keyPathLabel.setText(keyFilePath.toOSString());
passwordLabel.setText(StringUtil
.makeFormLabel(Messages.CommonFTPConnectionPointPropertyDialog_Passphrase));
try
{
boolean passphraseProtected = SecureUtils.isKeyPassphraseProtected(keyFilePath.toFile());
makeVisible(passwordLabel, passphraseProtected);
makeVisible(passwordText, passphraseProtected);
makeVisible(savePasswordButton, passphraseProtected);
}
catch (CoreException e)
{
IdeLog.logError(SecureFTPUIPlugin.getDefault(), e);
}
}
updateLayout();
}
super.loadPropertiesFrom(connectionPoint);
}
@Override
protected boolean savePropertiesTo(IBaseRemoteConnectionPoint connectionPoint)
{
boolean updated = false;
if (connectionPoint instanceof SFTPConnectionPoint)
{
SFTPConnectionPoint sftpConnectionPoint = (SFTPConnectionPoint) connectionPoint;
if (keyAuthButton.getSelection())
{
IPath keyFilePath = Path.fromPortableString(keyPathLabel.getText());
if (!connectionPoint.getPath().equals(keyFilePath))
{
sftpConnectionPoint.setKeyFilePath(keyFilePath);
updated = true;
}
}
}
return super.savePropertiesTo(connectionPoint) || updated;
}
private void updateProtocolButton()
{
int currentIndex = Arrays.asList(PROTOCOL_TYPES).indexOf(getConnectionPointType());
if (currentIndex == -1)
{
currentIndex = 0;
}
protocolButton.setText(PROTOCOL_TYPES[currentIndex].getName());
}
private void updateKeyAuth()
{
boolean keyAuthEnabled = ISFTPConnectionPoint.TYPE_SFTP.equals(getConnectionPointType().getType());
makeVisible(keyAuthComposite, keyAuthEnabled);
keyAuthButton.setSelection(false);
changeKeyAuthentication();
}
private void updateAdvancedOptions()
{
int currentIndex = Arrays.asList(PROTOCOL_TYPES).indexOf(getConnectionPointType());
if (currentIndex == -1)
{
currentIndex = 0;
}
for (Composite composite : advancedOptionsComposites)
{
makeVisible(composite, false);
}
Composite advancedOptionComposite = advancedOptionsComposites[currentIndex];
makeVisible(advancedOptionComposite, true);
advancedOptions = (IOptionsComposite) advancedOptionComposite;
}
private void changeProtocolType(ConnectionPointType newType)
{
if (newType == null || newType.equals(getConnectionPointType()))
{
return;
}
connectionType = newType;
updateProtocolButton();
updateKeyAuth();
updateAdvancedOptions();
updateLayout();
ftpConnectionPoint = getOrCreateConnectionPoint(connectionType);
advancedOptions.loadPropertiesFrom(ftpConnectionPoint);
}
private void changeKeyAuthentication()
{
boolean enabled = keyAuthButton.getSelection();
if (enabled)
{
FileDialog dlg;
String ssh_home = SecureUtils.getSSH_HOME();
while (true)
{
dlg = new FileDialog(getShell(), SWT.OPEN);
dlg.setText(Messages.CommonFTPConnectionPointPropertyDialog_SpecifyPrivateKey);
if (ssh_home != null && ssh_home.length() != 0)
{
File dir = new File(ssh_home);
if (dir.exists() && dir.isDirectory())
{
dlg.setFilterPath(ssh_home);
for (String key : SecureUtils.getPrivateKeys())
{
if (new File(dir, key).exists())
{
dlg.setFileName(key);
break;
}
}
}
}
String keyFilePath = dlg.open();
if (keyFilePath == null)
{
keyAuthButton.setSelection(false);
return;
}
try
{
boolean passphraseProtected = SecureUtils.isKeyPassphraseProtected(new File(keyFilePath));
makeVisible(passwordLabel, passphraseProtected);
makeVisible(passwordText, passphraseProtected);
makeVisible(savePasswordButton, passphraseProtected);
}
catch (CoreException e)
{
UIUtils.showErrorMessage(Messages.CommonFTPConnectionPointPropertyDialog_ERR_PrivateKey, e
.getLocalizedMessage());
continue;
}
keyPathLabel.setText(keyFilePath);
break;
}
passwordText.setText(""); //$NON-NLS-1$
}
else
{
keyPathLabel.setText(Messages.CommonFTPConnectionPointPropertyDialog_NoPrivateKeySelected);
makeVisible(passwordLabel, true);
makeVisible(passwordText, true);
makeVisible(savePasswordButton, true);
}
updateLayout();
passwordLabel.setText(StringUtil
.makeFormLabel(enabled ? Messages.CommonFTPConnectionPointPropertyDialog_Passphrase
: Messages.CommonFTPConnectionPointPropertyDialog_Password));
savePasswordButton.setSelection(false);
}
private void updateLayout()
{
Composite parent = getParent();
if (parent != null)
{
parent.layout(true, true);
if (listener != null)
{
listener.layoutShell();
}
}
}
private static void makeVisible(Control control, boolean visible)
{
control.setVisible(visible);
((GridData) control.getLayoutData()).exclude = !visible;
}
}