/*
* Copyright 2011-2017 Amazon Technologies, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://aws.amazon.com/apache2.0
*
* This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
* OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and
* limitations under the License.
*/
package com.amazonaws.eclipse.codecommit.widgets;
import static com.amazonaws.eclipse.core.model.GitCredentialsDataModel.P_PASSWORD;
import static com.amazonaws.eclipse.core.model.GitCredentialsDataModel.P_SHOW_PASSWORD;
import static com.amazonaws.eclipse.core.model.GitCredentialsDataModel.P_USERNAME;
import static com.amazonaws.eclipse.core.ui.wizards.WizardWidgetFactory.newLink;
import static com.amazonaws.eclipse.core.ui.wizards.WizardWidgetFactory.newPushButton;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.text.ParseException;
import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.beans.PojoObservables;
import org.eclipse.core.databinding.validation.IValidator;
import org.eclipse.jface.dialogs.MessageDialog;
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.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.FileDialog;
import com.amazonaws.eclipse.codecommit.credentials.GitCredential;
import com.amazonaws.eclipse.core.AwsToolkitCore;
import com.amazonaws.eclipse.core.model.GitCredentialsDataModel;
import com.amazonaws.eclipse.core.ui.WebLinkListener;
import com.amazonaws.eclipse.core.widget.CheckboxComplex;
import com.amazonaws.eclipse.core.widget.TextComplex;
import com.amazonaws.eclipse.databinding.NotEmptyValidator;
/**
* A complex composite for configuring Git credentials.
*/
public class GitCredentialsComposite extends Composite {
private static final String GIT_CREDENTIALS_DOC =
"http://docs.aws.amazon.com/codecommit/latest/userguide/setting-up-gc.html#setting-up-gc-iam";
private TextComplex usernameComplex;
private TextComplex passwordComplex;
private CheckboxComplex showPasswordComplex;
private Button browseButton;
public GitCredentialsComposite(Composite parent, DataBindingContext dataBindingContext, GitCredentialsDataModel dataModel) {
this(parent, dataBindingContext, dataModel, null, null);
}
public GitCredentialsComposite(Composite parent, DataBindingContext dataBindingContext, GitCredentialsDataModel dataModel,
IValidator usernameValidator, IValidator passwordValidator) {
super(parent, SWT.NONE);
setLayout(new GridLayout(2, false));
setLayoutData(new GridData(GridData.FILL_BOTH));
createControl(dataBindingContext, dataModel, usernameValidator, passwordValidator);
}
public void populateGitCredential(String username, String password) {
usernameComplex.setText(username);
passwordComplex.setText(password);
}
private void createControl(DataBindingContext context, GitCredentialsDataModel dataModel,
IValidator usernameValidator, IValidator passwordValidator) {
newLink(this, new WebLinkListener(), String.format(
"You can manually copy and paste Git credentials for AWS CodeCommit below. "
+ "Alternately, you can import them from a downloaded .csv file. To learn how to generate Git credentials, see "
+ "<a href=\"%s\">Create Git Credentials for HTTPS Connections to AWS CodeCommit</a>.", GIT_CREDENTIALS_DOC), 2);
usernameComplex = TextComplex.builder()
.composite(this)
.dataBindingContext(context)
.pojoObservableValue(PojoObservables.observeValue(dataModel, P_USERNAME))
.validator(usernameValidator == null ? new NotEmptyValidator("User name must be provided!") : usernameValidator)
.labelValue("User name:")
.defaultValue(dataModel.getUsername())
.build();
passwordComplex = TextComplex.builder()
.composite(this)
.dataBindingContext(context)
.pojoObservableValue(PojoObservables.observeValue(dataModel, P_PASSWORD))
.validator(passwordValidator == null ? new NotEmptyValidator("Password must be provided!") : passwordValidator)
.labelValue("Password: ")
.defaultValue(dataModel.getPassword())
.build();
showPasswordComplex = CheckboxComplex.builder()
.composite(this)
.dataBindingContext(context)
.pojoObservableValue(PojoObservables.observeValue(dataModel, P_SHOW_PASSWORD))
.labelValue("Show password")
.selectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
onShowPasswordCheckboxSelection();
}
})
.defaultValue(dataModel.isShowPassword())
.build();
browseButton = newPushButton(this, "Import from csv file");
browseButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
browseButton.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
FileDialog dialog = new FileDialog(getShell(), SWT.SINGLE);
String path = dialog.open();
if (path == null) return;
GitCredential gitCredential = loadGitCredential(new File(path));
usernameComplex.setText(gitCredential.getUsername());
passwordComplex.setText(gitCredential.getPassword());
}
});
onShowPasswordCheckboxSelection();
}
private void onShowPasswordCheckboxSelection() {
passwordComplex.getText().setEchoChar(showPasswordComplex.getCheckbox().getSelection() ? '\0' : '*');
}
private GitCredential loadGitCredential(File csvFile) {
BufferedReader bufferedReader = null;
GitCredential gitCredential = new GitCredential("", "");
try {
bufferedReader = new BufferedReader(new FileReader(csvFile));
String line = bufferedReader.readLine(); // the first line of the default csv file is metadata
if (line == null) {
throw new ParseException("The csv file is empty", 1);
}
line = bufferedReader.readLine(); // the second line of the default csv file contains the credentials separated with ','
if (line == null) {
throw new ParseException("Invalid Git credential csv file format!", 2);
}
String[] tokens = line.split(",");
if (tokens.length != 2) {
throw new ParseException(
"The csv file must have two columns!", 2);
}
gitCredential.setUsername(tokens[0].trim());
gitCredential.setPassword(tokens[1].trim());
} catch (Exception e) {
AwsToolkitCore.getDefault().logWarning("Failed to load gitCredentials file for Git credentials!", e);
new MessageDialog(getShell(), "Error loading Git credentials!",
null, e.getMessage(), MessageDialog.ERROR, new String[] {"OK"}, 0).open();
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException e) {
}
}
}
return gitCredential;
}
}