diff --git a/java/com.amazon.aws.aws-java-api/build.gradle b/java/com.amazon.aws.aws-java-api/build.gradle index 99f8bcbb76a..1a31b78c0c5 100644 --- a/java/com.amazon.aws.aws-java-api/build.gradle +++ b/java/com.amazon.aws.aws-java-api/build.gradle @@ -14,6 +14,7 @@ dependencies { implementation 'software.amazon.awssdk:elasticloadbalancingv2' implementation 'software.amazon.awssdk:autoscaling' implementation 'software.amazon.awssdk:sts' + implementation 'software.amazon.awssdk:iam' implementation group: 'software.amazon.awssdk', name: 'sdk-core', classifier: 'sources' implementation group: 'software.amazon.awssdk', name: 'arns', classifier: 'sources' implementation group: 'software.amazon.awssdk', name: 'aws-core', classifier: 'sources' @@ -29,6 +30,7 @@ dependencies { implementation group: 'software.amazon.awssdk', name: 'elasticloadbalancingv2', classifier: 'sources' implementation group: 'software.amazon.awssdk', name: 'autoscaling', classifier: 'sources' implementation group: 'software.amazon.awssdk', name: 'sts', classifier: 'sources' + implementation group: 'software.amazon.awssdk', name: 'iam', classifier: 'sources' } task downloadLibs(type: Copy) { into file('lib') diff --git a/java/com.sap.sailing.gwt.ui/Debug SailingGWT SDM on Chrome.launch b/java/com.sap.sailing.gwt.ui/Debug SailingGWT SDM on Chrome.launch index 3b9733c2e17..7cde37041b4 100644 --- a/java/com.sap.sailing.gwt.ui/Debug SailingGWT SDM on Chrome.launch +++ b/java/com.sap.sailing.gwt.ui/Debug SailingGWT SDM on Chrome.launch @@ -9,10 +9,6 @@ - - - - diff --git a/java/com.sap.sailing.gwt.ui/GWT Sailing SDM (Home+Admin+Raceboard).launch b/java/com.sap.sailing.gwt.ui/GWT Sailing SDM (Home+Admin+Raceboard).launch index 451b0abcafd..40cc8026f00 100644 --- a/java/com.sap.sailing.gwt.ui/GWT Sailing SDM (Home+Admin+Raceboard).launch +++ b/java/com.sap.sailing.gwt.ui/GWT Sailing SDM (Home+Admin+Raceboard).launch @@ -1,114 +1,114 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/AwsAccessKeyProvider.java b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/AwsAccessKeyProvider.java index ea1e43711bd..449470d93c1 100755 --- a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/AwsAccessKeyProvider.java +++ b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/AwsAccessKeyProvider.java @@ -1,6 +1,5 @@ package com.sap.sailing.landscape.ui.client; public interface AwsAccessKeyProvider { - String getAwsAccessKeyId(); - String getAwsSecret(); + boolean hasValidSessionCredentials(); } diff --git a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/AwsMfaLoginWidget.java b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/AwsMfaLoginWidget.java new file mode 100755 index 00000000000..494520470d7 --- /dev/null +++ b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/AwsMfaLoginWidget.java @@ -0,0 +1,149 @@ +package com.sap.sailing.landscape.ui.client; + +import java.util.HashSet; +import java.util.Set; + +import com.google.gwt.user.client.rpc.AsyncCallback; +import com.google.gwt.user.client.ui.Button; +import com.google.gwt.user.client.ui.Grid; +import com.google.gwt.user.client.ui.HorizontalPanel; +import com.google.gwt.user.client.ui.Label; +import com.google.gwt.user.client.ui.PasswordTextBox; +import com.google.gwt.user.client.ui.TextBox; +import com.google.gwt.user.client.ui.VerticalPanel; +import com.sap.sailing.landscape.ui.client.i18n.StringMessages; +import com.sap.sse.gwt.client.ErrorReporter; +import com.sap.sse.gwt.client.Notification; +import com.sap.sse.gwt.client.Notification.NotificationType; +import com.sap.sse.gwt.client.dialog.DialogUtils; +import com.sap.sse.security.ui.client.UserService; + +public class AwsMfaLoginWidget extends VerticalPanel implements AwsAccessKeyProvider { + private final static String AWS_ACCESS_KEY_USER_PREFERENCE = "aws.access.key"; + + private final TextBox awsAccessKeyTextBox; + private final PasswordTextBox awsSecretPasswordTextBox; + private final TextBox mfaTokenCodeTextBox; + private final LandscapeManagementWriteServiceAsync landscapeManagementService; + private final ErrorReporter errorReporter; + private final Grid awsCredentialsGrid; + private final Set listeners; + private boolean hasValidSessionCredentials; + + @FunctionalInterface + public static interface AwsMfaLoginListener { + void awsSessionStatusChanged(boolean hasValidSessionCredentials); + } + + public AwsMfaLoginWidget(LandscapeManagementWriteServiceAsync landscapeManagementService, ErrorReporter errorReporter, + UserService userService, StringMessages stringMessages) { + super(); + this.listeners = new HashSet<>(); + this.landscapeManagementService = landscapeManagementService; + this.errorReporter = errorReporter; + final HorizontalPanel buttonPanel = new HorizontalPanel(); + this.add(buttonPanel); + final Button refreshButton = new Button(stringMessages.refresh()); + buttonPanel.add(refreshButton); + final Button logoutButton = new Button(stringMessages.logout()); + buttonPanel.add(logoutButton); + awsCredentialsGrid = new Grid(4, 2); + this.add(awsCredentialsGrid); + awsCredentialsGrid.setWidget(0, 0, new Label(stringMessages.awsAccessKey())); + awsAccessKeyTextBox = new TextBox(); + userService.getPreference(AWS_ACCESS_KEY_USER_PREFERENCE, new AsyncCallback() { + @Override + public void onFailure(Throwable caught) { + errorReporter.reportError(caught.getMessage()); + } + + @Override + public void onSuccess(String result) { + awsAccessKeyTextBox.setValue(result); + } + }); + awsAccessKeyTextBox.addValueChangeHandler(e->userService.setPreference(AWS_ACCESS_KEY_USER_PREFERENCE, awsAccessKeyTextBox.getValue(), + new AsyncCallback() { + @Override + public void onFailure(Throwable caught) { + errorReporter.reportError(caught.getMessage()); + } + @Override + public void onSuccess(Void result) { + } + })); + awsCredentialsGrid.setWidget(0, 1, awsAccessKeyTextBox); + awsCredentialsGrid.setWidget(1, 0, new Label(stringMessages.awsSecret())); + awsSecretPasswordTextBox = new PasswordTextBox(); + awsCredentialsGrid.setWidget(1, 1, awsSecretPasswordTextBox); + mfaTokenCodeTextBox = new TextBox(); + awsCredentialsGrid.setWidget(2, 0, new Label(stringMessages.mfaTokenCode())); + awsCredentialsGrid.setWidget(2, 1, mfaTokenCodeTextBox); + final Button loginButton = new Button(stringMessages.login()); + awsCredentialsGrid.setWidget(3, 0, loginButton); + awsCredentialsGrid.setVisible(false); + refreshButton.addClickHandler(e->checkSessionCredentials()); + loginButton.addClickHandler(e->landscapeManagementService.createMfaSessionCredentials(awsAccessKeyTextBox.getValue(), awsSecretPasswordTextBox.getValue(), mfaTokenCodeTextBox.getValue(), + new AsyncCallback() { + @Override + public void onFailure(Throwable caught) { + errorReporter.reportError(stringMessages.invalidCredentialsNoSessionCreated(caught.getMessage())); + checkSessionCredentials(); + } + + @Override + public void onSuccess(Void result) { + Notification.notify(stringMessages.loggedInSuccessfully(), NotificationType.SUCCESS); + checkSessionCredentials(); + } + })); + logoutButton.addClickHandler(e->landscapeManagementService.clearSessionCredentials(new AsyncCallback() { + @Override + public void onFailure(Throwable caught) { + errorReporter.reportError(caught.getMessage()); + checkSessionCredentials(); + } + + @Override + public void onSuccess(Void result) { + Notification.notify(stringMessages.loggedOutSuccessfully(), NotificationType.SUCCESS); + checkSessionCredentials(); + } + })); + DialogUtils.linkEnterToButton(loginButton, awsAccessKeyTextBox, awsSecretPasswordTextBox, mfaTokenCodeTextBox); + checkSessionCredentials(); + } + + public void addListener(AwsMfaLoginListener listener) { + listeners.add(listener); + } + + @Override + public boolean hasValidSessionCredentials() { + return hasValidSessionCredentials; + } + + private void setHasValidSessionCredentials(boolean validSessionCredentials) { + final boolean oldHasValidSessionCredentials = hasValidSessionCredentials; + hasValidSessionCredentials = validSessionCredentials; + awsCredentialsGrid.setVisible(!validSessionCredentials); + if (oldHasValidSessionCredentials != validSessionCredentials) { + listeners.forEach(l->l.awsSessionStatusChanged(validSessionCredentials)); + } + } + + private void checkSessionCredentials() { + landscapeManagementService.hasValidSessionCredentials(new AsyncCallback() { + @Override + public void onFailure(Throwable caught) { + setHasValidSessionCredentials(false); + errorReporter.reportError(caught.getMessage()); + } + + @Override + public void onSuccess(Boolean hasValidCredentials) { + setHasValidSessionCredentials(hasValidCredentials); + } + }); + } +} diff --git a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/LandscapeManagementPanel.java b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/LandscapeManagementPanel.java index 5fa962e9030..e1a69539dd6 100755 --- a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/LandscapeManagementPanel.java +++ b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/LandscapeManagementPanel.java @@ -16,11 +16,7 @@ import com.google.gwt.user.client.Window; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.rpc.ServiceDefTarget; import com.google.gwt.user.client.ui.CaptionPanel; -import com.google.gwt.user.client.ui.Grid; import com.google.gwt.user.client.ui.HorizontalPanel; -import com.google.gwt.user.client.ui.Label; -import com.google.gwt.user.client.ui.PasswordTextBox; -import com.google.gwt.user.client.ui.TextBox; import com.google.gwt.user.client.ui.VerticalPanel; import com.sap.sailing.landscape.ui.client.i18n.StringMessages; import com.sap.sailing.landscape.ui.shared.AmazonMachineImageDTO; @@ -71,7 +67,7 @@ import com.sap.sse.security.ui.client.UserService; * @author Axel Uhl (D043530) * */ -public class LandscapeManagementPanel extends VerticalPanel implements AwsAccessKeyProvider { +public class LandscapeManagementPanel extends VerticalPanel { private final LandscapeManagementWriteServiceAsync landscapeManagementService; private final TableWrapperWithSingleSelectionAndFilter regionsTable; private final TableWrapperWithSingleSelectionAndFilter mongoEndpointsTable; @@ -79,10 +75,8 @@ public class LandscapeManagementPanel extends VerticalPanel implements AwsAccess private final TableWrapperWithSingleSelectionAndFilter machineImagesTable; private final BusyIndicator machineImagesBusy; private final SshKeyManagementPanel sshKeyManagementPanel; - private final TextBox awsAccessKeyTextBox; // TODO bug4811: use landscapeManagementService.hasValidSessionCredentials to find out and show popup with access key/secret/MFA token code to produce them - private final PasswordTextBox awsSecretPasswordTextBox; private final ErrorReporter errorReporter; - private final static String AWS_ACCESS_KEY_USER_PREFERENCE = "aws.access.key"; + private final AwsMfaLoginWidget mfaLoginWidget; private final static String AWS_DEFAULT_REGION_USER_PREFERENCE = "aws.region.default"; public LandscapeManagementPanel(StringMessages stringMessages, UserService userService, @@ -93,35 +87,9 @@ public class LandscapeManagementPanel extends VerticalPanel implements AwsAccess add(awsCredentialsAndSshKeys); final CaptionPanel awsCredentialsPanel = new CaptionPanel(stringMessages.awsCredentials()); awsCredentialsAndSshKeys.add(awsCredentialsPanel); - final Grid awsCredentialsGrid = new Grid(2, 2); - awsCredentialsPanel.add(awsCredentialsGrid); - awsCredentialsGrid.setWidget(0, 0, new Label(stringMessages.awsAccessKey())); - awsAccessKeyTextBox = new TextBox(); - userService.getPreference(AWS_ACCESS_KEY_USER_PREFERENCE, new AsyncCallback() { - @Override - public void onFailure(Throwable caught) { - errorReporter.reportError(caught.getMessage()); - } - - @Override - public void onSuccess(String result) { - awsAccessKeyTextBox.setValue(result); - } - }); - awsAccessKeyTextBox.addValueChangeHandler(e->userService.setPreference(AWS_ACCESS_KEY_USER_PREFERENCE, awsAccessKeyTextBox.getValue(), - new AsyncCallback() { - @Override - public void onFailure(Throwable caught) { - errorReporter.reportError(caught.getMessage()); - } - @Override - public void onSuccess(Void result) { - } - })); - awsCredentialsGrid.setWidget(0, 1, awsAccessKeyTextBox); - awsCredentialsGrid.setWidget(1, 0, new Label(stringMessages.awsSecret())); - awsSecretPasswordTextBox = new PasswordTextBox(); - awsCredentialsGrid.setWidget(1, 1, awsSecretPasswordTextBox); + mfaLoginWidget = new AwsMfaLoginWidget(landscapeManagementService, errorReporter, userService, stringMessages); + mfaLoginWidget.addListener(validSession->refreshAllThatNeedsAwsCredentials()); + awsCredentialsPanel.add(mfaLoginWidget); regionsTable = new TableWrapperWithSingleSelectionAndFilter( stringMessages, errorReporter, /* enablePager */ false, /* entity identity comparator */ Optional.empty(), GWT.create(AdminConsoleTableResources.class), @@ -133,7 +101,7 @@ public class LandscapeManagementPanel extends VerticalPanel implements AwsAccess } }; sshKeyManagementPanel = new SshKeyManagementPanel(stringMessages, userService, - landscapeManagementService, tableResources, errorReporter, /* access key provider */ this, regionsTable.getSelectionModel()); + landscapeManagementService, tableResources, errorReporter, /* access key provider */ mfaLoginWidget, regionsTable.getSelectionModel()); final CaptionPanel sshKeysCaptionPanel = new CaptionPanel(stringMessages.sshKeys()); awsCredentialsAndSshKeys.add(sshKeysCaptionPanel); sshKeysCaptionPanel.add(sshKeyManagementPanel); @@ -225,14 +193,6 @@ public class LandscapeManagementPanel extends VerticalPanel implements AwsAccess refreshMachineImagesTable(); storeRegionSelection(userService, selectedRegion); }); - awsAccessKeyTextBox.addChangeHandler(e->{ - GWT.log("awsAccessKeyTextBox changed"); - refreshAllThatNeedsAwsCredentials(userService); - }); - awsSecretPasswordTextBox.addChangeHandler(e->{ - GWT.log("awsSecretPasswordTextBox changed"); - refreshAllThatNeedsAwsCredentials(userService); - }); // TODO upon region selection show AppServer clusters in region // TODO try to identify archive servers // TODO support creating a new app server cluster @@ -270,16 +230,11 @@ public class LandscapeManagementPanel extends VerticalPanel implements AwsAccess }); } - private void refreshAllThatNeedsAwsCredentials(UserService userService) { - if (hasAwsCredentialsFilledIn()) { - refreshMongoEndpointsTable(); - refreshMachineImagesTable(); - sshKeyManagementPanel.showKeysInRegion(awsAccessKeyTextBox.getValue(), awsSecretPasswordTextBox.getValue(), regionsTable.getSelectionModel().getSelectedObject()); - } - } - - private boolean hasAwsCredentialsFilledIn() { - return Util.hasLength(awsAccessKeyTextBox.getValue()) && Util.hasLength(awsSecretPasswordTextBox.getValue()); + private void refreshAllThatNeedsAwsCredentials() { + refreshMongoEndpointsTable(); + refreshMachineImagesTable(); + sshKeyManagementPanel.showKeysInRegion(mfaLoginWidget.hasValidSessionCredentials() ? + regionsTable.getSelectionModel().getSelectedObject() : null); } private void storeRegionSelection(UserService userService, String selectedRegion) { @@ -295,21 +250,20 @@ public class LandscapeManagementPanel extends VerticalPanel implements AwsAccess @Override public void ok(MongoScalingInstructionsDTO mongoScalingInstructions) { mongoEndpointsBusy.setBusy(true); - landscapeManagementService.scaleMongo(awsAccessKeyTextBox.getValue(), awsSecretPasswordTextBox.getValue(), selectedRegion, - mongoScalingInstructions, new AsyncCallback() { - @Override - public void onFailure(Throwable caught) { - mongoEndpointsBusy.setBusy(false); - errorReporter.reportError(caught.getMessage()); - } + landscapeManagementService.scaleMongo(selectedRegion, mongoScalingInstructions, new AsyncCallback() { + @Override + public void onFailure(Throwable caught) { + mongoEndpointsBusy.setBusy(false); + errorReporter.reportError(caught.getMessage()); + } - @Override - public void onSuccess(Void result) { - mongoEndpointsBusy.setBusy(false); - Notification.notify(stringMessages.successfullyScaledMongoDB(), NotificationType.SUCCESS); - refreshMongoEndpointsTable(); - } - }); + @Override + public void onSuccess(Void result) { + mongoEndpointsBusy.setBusy(false); + Notification.notify(stringMessages.successfullyScaledMongoDB(), NotificationType.SUCCESS); + refreshMongoEndpointsTable(); + } + }); } @Override @@ -329,60 +283,49 @@ public class LandscapeManagementPanel extends VerticalPanel implements AwsAccess } private void refreshMongoEndpointsTable() { - if (hasAwsCredentialsFilledIn()) { - mongoEndpointsTable.getDataProvider().getList().clear(); - if (regionsTable.getSelectionModel().getSelectedObject() != null) { - mongoEndpointsBusy.setBusy(true); - landscapeManagementService.getMongoEndpoints(awsAccessKeyTextBox.getValue(), awsSecretPasswordTextBox.getValue(), - regionsTable.getSelectionModel().getSelectedObject(), new AsyncCallback>() { - @Override - public void onFailure(Throwable caught) { - errorReporter.reportError(caught.getMessage()); - mongoEndpointsBusy.setBusy(false); - } - - @Override - public void onSuccess(ArrayList mongoEndpointDTOs) { - mongoEndpointsTable.refresh(mongoEndpointDTOs); - mongoEndpointsBusy.setBusy(false); - } - }); - } else { - mongoEndpointsTable.getDataProvider().getList().clear(); - } + mongoEndpointsTable.getFilterPanel().removeAll(); + if (mfaLoginWidget.hasValidSessionCredentials() && regionsTable.getSelectionModel().getSelectedObject() != null) { + mongoEndpointsBusy.setBusy(true); + landscapeManagementService.getMongoEndpoints(regionsTable.getSelectionModel().getSelectedObject(), new AsyncCallback>() { + @Override + public void onFailure(Throwable caught) { + errorReporter.reportError(caught.getMessage()); + mongoEndpointsBusy.setBusy(false); + } + + @Override + public void onSuccess(ArrayList mongoEndpointDTOs) { + mongoEndpointsTable.refresh(mongoEndpointDTOs); + mongoEndpointsBusy.setBusy(false); + } + }); } } private void refreshMachineImagesTable() { - if (hasAwsCredentialsFilledIn()) { - machineImagesTable.getDataProvider().getList().clear(); - if (regionsTable.getSelectionModel().getSelectedObject() != null) { - machineImagesBusy.setBusy(true); - landscapeManagementService.getAmazonMachineImages(awsAccessKeyTextBox.getValue(), awsSecretPasswordTextBox.getValue(), - regionsTable.getSelectionModel().getSelectedObject(), new AsyncCallback>() { - @Override - public void onFailure(Throwable caught) { - errorReporter.reportError(caught.getMessage()); - machineImagesBusy.setBusy(false); - } - - @Override - public void onSuccess(ArrayList machineImagesDTOs) { - machineImagesTable.refresh(machineImagesDTOs); - machineImagesBusy.setBusy(false); - } - }); - } else { - machineImagesTable.getDataProvider().getList().clear(); - } + machineImagesTable.getFilterPanel().removeAll(); + if (mfaLoginWidget.hasValidSessionCredentials() && regionsTable.getSelectionModel().getSelectedObject() != null) { + machineImagesBusy.setBusy(true); + landscapeManagementService.getAmazonMachineImages(regionsTable.getSelectionModel().getSelectedObject(), new AsyncCallback>() { + @Override + public void onFailure(Throwable caught) { + errorReporter.reportError(caught.getMessage()); + machineImagesBusy.setBusy(false); + } + + @Override + public void onSuccess(ArrayList machineImagesDTOs) { + machineImagesTable.refresh(machineImagesDTOs); + machineImagesBusy.setBusy(false); + } + }); } } private void upgradeMachineImage(final StringMessages stringMessages, final AmazonMachineImageDTO machineImageToUpgrade) { Notification.notify(stringMessages.startedImageUpgrade(machineImageToUpgrade.getName(), machineImageToUpgrade.getId(), machineImageToUpgrade.getRegionId()), NotificationType.INFO); machineImagesBusy.setBusy(true); - landscapeManagementService.upgradeAmazonMachineImage(awsAccessKeyTextBox.getValue(), awsSecretPasswordTextBox.getValue(), - machineImageToUpgrade.getRegionId(), machineImageToUpgrade.getId(), + landscapeManagementService.upgradeAmazonMachineImage(machineImageToUpgrade.getRegionId(), machineImageToUpgrade.getId(), new AsyncCallback() { @Override public void onFailure(Throwable caught) { @@ -404,8 +347,7 @@ public class LandscapeManagementPanel extends VerticalPanel implements AwsAccess private void removeMachineImage(final StringMessages stringMessages, final AmazonMachineImageDTO machineImageToRemove) { if (Window.confirm(stringMessages.doYouReallyWantToRemoveMachineImage(machineImageToRemove.getName(), machineImageToRemove.getId(), machineImageToRemove.getRegionId()))) { - landscapeManagementService.removeAmazonMachineImage(awsAccessKeyTextBox.getValue(), awsSecretPasswordTextBox.getValue(), - machineImageToRemove.getRegionId(), machineImageToRemove.getId(), + landscapeManagementService.removeAmazonMachineImage(machineImageToRemove.getRegionId(), machineImageToRemove.getId(), new AsyncCallback() { @Override public void onFailure(Throwable caught) { @@ -430,14 +372,4 @@ public class LandscapeManagementPanel extends VerticalPanel implements AwsAccess RemoteServiceMappingConstants.landscapeManagementServiceRemotePath, HEADER_FORWARD_TO_MASTER); return result; } - - @Override - public String getAwsAccessKeyId() { - return awsAccessKeyTextBox.getValue(); - } - - @Override - public String getAwsSecret() { - return awsSecretPasswordTextBox.getValue(); - } } diff --git a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/LandscapeManagementWriteService.java b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/LandscapeManagementWriteService.java index 3c5f1316942..879dfabef0b 100755 --- a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/LandscapeManagementWriteService.java +++ b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/LandscapeManagementWriteService.java @@ -13,30 +13,30 @@ public interface LandscapeManagementWriteService extends RemoteService { ArrayList getInstanceTypes(); - ArrayList getMongoEndpoints(String awsAccessKey, String awsSecret, String region); + ArrayList getMongoEndpoints(String region); - MongoEndpointDTO getMongoEndpoint(String awsAccessKey, String awsSecret, String region, String replicaSetName); + MongoEndpointDTO getMongoEndpoint(String region, String replicaSetName); - ArrayList getSshKeys(String awsAccessKey, String awsSecret, String regionId); + ArrayList getSshKeys(String regionId); - void removeSshKey(String awsAccessKey, String awsSecret, SSHKeyPairDTO keyPair); + void removeSshKey(SSHKeyPairDTO keyPair); - SSHKeyPairDTO generateSshKeyPair(String awsAccessKey, String awsSecret, String regionId, String keyName, String privateKeyEncryptionPassphrase); + SSHKeyPairDTO generateSshKeyPair(String regionId, String keyName, String privateKeyEncryptionPassphrase); - SSHKeyPairDTO addSshKeyPair(String awsAccessKey, String awsSecret, String regionId, String keyName, String publicKey, + SSHKeyPairDTO addSshKeyPair(String regionId, String keyName, String publicKey, String encryptedPrivateKey) throws Exception; byte[] getEncryptedSshPrivateKey(String regionId, String keyName) throws Exception; byte[] getSshPublicKey(String regionId, String keyName) throws Exception; - ArrayList getAmazonMachineImages(String awsAccessKey, String awsSecret, String region); + ArrayList getAmazonMachineImages(String region); - void removeAmazonMachineImage(String awsAccessKey, String awsSecret, String region, String machineImageId); + void removeAmazonMachineImage(String region, String machineImageId); - AmazonMachineImageDTO upgradeAmazonMachineImage(String awsAccessKey, String awsSecret, String region, String machineImageId) throws Exception; + AmazonMachineImageDTO upgradeAmazonMachineImage(String region, String machineImageId) throws Exception; - void scaleMongo(String awsAccessKey, String awsSecret, String region, MongoScalingInstructionsDTO mongoScalingInstructions) throws Exception; + void scaleMongo(String region, MongoScalingInstructionsDTO mongoScalingInstructions) throws Exception; /** * For a combination of an AWS access key ID, the corresponding secret plus an MFA token code produces new session diff --git a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/LandscapeManagementWriteServiceAsync.java b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/LandscapeManagementWriteServiceAsync.java index 9f9136fe4de..28358938c01 100755 --- a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/LandscapeManagementWriteServiceAsync.java +++ b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/LandscapeManagementWriteServiceAsync.java @@ -13,50 +13,44 @@ public interface LandscapeManagementWriteServiceAsync { void getInstanceTypes(AsyncCallback> callback); - void getMongoEndpoints(String awsAccessKey, String awsSecret, String regionId, - AsyncCallback> callback); + void getMongoEndpoints(String regionId, AsyncCallback> callback); - void getMongoEndpoint(String awsAccessKey, String awsSecret, String region, String replicaSetName, + void getMongoEndpoint(String region, String replicaSetName, AsyncCallback callback); /** * The calling subject will see only those keys for which it has the {@code READ} permission. */ - void getSshKeys(String awsAccessKey, String awsSecret, String regionId, - AsyncCallback> callback); + void getSshKeys(String regionId, AsyncCallback> callback); /** * The calling subject must have {@code DELETE} permission for the key requested. */ - void removeSshKey(String awsAccessKey, String awsSecret, SSHKeyPairDTO keyPair, AsyncCallback asyncCallback); + void removeSshKey(SSHKeyPairDTO keyPair, AsyncCallback asyncCallback); /** * The calling subject must have {@code CREATE} permission for the key name and region requested as well as the * {@link CREATE_OBJECT} permission on the server on which this is called. */ - void generateSshKeyPair(String awsAccessKey, String awsSecret, String regionId, String keyName, - String privateKeyEncryptionPassphrase, AsyncCallback callback); + void generateSshKeyPair(String regionId, String keyName, String privateKeyEncryptionPassphrase, AsyncCallback callback); /** * The calling subject must have {@code CREATE} permission for the key requested as well as the * {@link CREATE_OBJECT} permission on the server on which this is called. */ - void addSshKeyPair(String awsAccessKey, String awsSecret, String regionId, String keyName, String publicKey, - String encryptedPrivateKey, AsyncCallback callback); + void addSshKeyPair(String regionId, String keyName, String publicKey, String encryptedPrivateKey, AsyncCallback callback); void getEncryptedSshPrivateKey(String regionId, String keyName, AsyncCallback callback); void getSshPublicKey(String regionId, String keyName, AsyncCallback callback); - void getAmazonMachineImages(String awsAccessKey, String awsSecret, String region, AsyncCallback> callback); + void getAmazonMachineImages(String region, AsyncCallback> callback); - void removeAmazonMachineImage(String awsAccessKey, String awsSecret, String region, String machineImageId, AsyncCallback callback); + void removeAmazonMachineImage(String region, String machineImageId, AsyncCallback callback); - void upgradeAmazonMachineImage(String awsAccessKey, String awsSecret, String region, String machineImageId, - AsyncCallback callback); + void upgradeAmazonMachineImage(String region, String machineImageId, AsyncCallback callback); - void scaleMongo(String awsAccessKey, String awsSecret, String region, - MongoScalingInstructionsDTO mongoScalingInstructions, AsyncCallback asyncCallback); + void scaleMongo(String region, MongoScalingInstructionsDTO mongoScalingInstructions, AsyncCallback asyncCallback); /** * Probes whether the current user has the {@code LANDSCAPE:MANAGE:AWS} permission and has previously diff --git a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/SshKeyManagementPanel.java b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/SshKeyManagementPanel.java index 8c657f2a639..78851457025 100755 --- a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/SshKeyManagementPanel.java +++ b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/SshKeyManagementPanel.java @@ -103,18 +103,17 @@ public class SshKeyManagementPanel extends VerticalPanel { sshKeyPairActionColumn.addAction(SshKeyPairImagesBarCell.ACTION_CHANGE_ACL, DefaultActions.CHANGE_ACL, configACL::openDialog); sshKeyPairActionColumn.addAction(SshKeyPairImagesBarCell.ACTION_REMOVE, DefaultActions.DELETE, - sshKeyPairDTO->landscapeManagementService.removeSshKey(awsAccessKeyProvider.getAwsAccessKeyId(), awsAccessKeyProvider.getAwsSecret(), - sshKeyPairDTO, new AsyncCallback() { - @Override - public void onFailure(Throwable caught) { - errorReporter.reportError(caught.getMessage()); - } + sshKeyPairDTO->landscapeManagementService.removeSshKey(sshKeyPairDTO, new AsyncCallback() { + @Override + public void onFailure(Throwable caught) { + errorReporter.reportError(caught.getMessage()); + } - @Override - public void onSuccess(Void result) { - sshKeyTable.remove(sshKeyPairDTO); - } - })); + @Override + public void onSuccess(Void result) { + sshKeyTable.remove(sshKeyPairDTO); + } + })); sshKeyPairActionColumn.addAction(SshKeyPairImagesBarCell.ACTION_SHOW_KEYS, DefaultActions.READ, sshKeyPairDTO->landscapeManagementService.getSshPublicKey(sshKeyPairDTO.getRegionId(), sshKeyPairDTO.getName(), new AsyncCallback() { @Override @@ -144,23 +143,21 @@ public class SshKeyManagementPanel extends VerticalPanel { sshKeyLoadingBusy = new SimpleBusyIndicator(); add(sshKeyLoadingBusy); buttonPanel.addRemoveAction(stringMessages.remove(), sshKeyTable.getSelectionModel(), /* withConfirmation */ true, ()->{ - landscapeManagementService.removeSshKey(awsAccessKeyProvider.getAwsAccessKeyId(), awsAccessKeyProvider.getAwsSecret(), - sshKeyTable.getSelectionModel().getSelectedObject(), new AsyncCallback() { - @Override - public void onFailure(Throwable caught) { - errorReporter.reportError(caught.getMessage()); - } + landscapeManagementService.removeSshKey(sshKeyTable.getSelectionModel().getSelectedObject(), new AsyncCallback() { + @Override + public void onFailure(Throwable caught) { + errorReporter.reportError(caught.getMessage()); + } - @Override - public void onSuccess(Void result) { - sshKeyTable.remove(sshKeyTable.getSelectionModel().getSelectedObject()); - } - }); + @Override + public void onSuccess(Void result) { + sshKeyTable.remove(sshKeyTable.getSelectionModel().getSelectedObject()); + } + }); }); regionSelectionModel.addSelectionChangeHandler(e->{ - if (Util.hasLength(awsAccessKeyProvider.getAwsSecret())) { - showKeysInRegion(awsAccessKeyProvider.getAwsAccessKeyId(), awsAccessKeyProvider.getAwsSecret(), - regionSelectionModel.getSelectedObject()); + if (awsAccessKeyProvider.hasValidSessionCredentials()) { + showKeysInRegion(regionSelectionModel.getSelectedObject()); addButton.setEnabled(regionSelectionModel.getSelectedObject() != null); generateButton.setEnabled(regionSelectionModel.getSelectedObject() != null); } @@ -180,8 +177,7 @@ public class SshKeyManagementPanel extends VerticalPanel { new DialogCallback>() { @Override public void ok(Triple keyPairNameAndPassphrases) { - landscapeManagementService.generateSshKeyPair(awsAccessKeyProvider.getAwsAccessKeyId(), - awsAccessKeyProvider.getAwsSecret(), regionSelectionModel.getSelectedObject(), + landscapeManagementService.generateSshKeyPair(regionSelectionModel.getSelectedObject(), keyPairNameAndPassphrases.getA(), keyPairNameAndPassphrases.getB(), new AsyncCallback() { @Override @@ -207,8 +203,7 @@ public class SshKeyManagementPanel extends VerticalPanel { new DialogCallback>() { @Override public void ok(Triple keyPairNameAndPublicAndPrivateKey) { - landscapeManagementService.addSshKeyPair(awsAccessKeyProvider.getAwsAccessKeyId(), awsAccessKeyProvider.getAwsSecret(), - regionSelectionModel.getSelectedObject(), keyPairNameAndPublicAndPrivateKey.getA(), + landscapeManagementService.addSshKeyPair(regionSelectionModel.getSelectedObject(), keyPairNameAndPublicAndPrivateKey.getA(), keyPairNameAndPublicAndPrivateKey.getB(), keyPairNameAndPublicAndPrivateKey.getC(), new AsyncCallback() { @Override @@ -229,11 +224,11 @@ public class SshKeyManagementPanel extends VerticalPanel { }).show(); } - public void showKeysInRegion(String awsAccessKey, String awsSecret, String regionId) { - sshKeyTable.getDataProvider().getList().clear(); + public void showKeysInRegion(String regionId) { + sshKeyTable.getFilterPanel().removeAll(); if (regionId != null) { sshKeyLoadingBusy.setBusy(true); - landscapeManagementService.getSshKeys(awsAccessKey, awsSecret, regionId, new AsyncCallback>() { + landscapeManagementService.getSshKeys(regionId, new AsyncCallback>() { @Override public void onFailure(Throwable caught) { errorReporter.reportError(caught.getMessage()); @@ -246,8 +241,6 @@ public class SshKeyManagementPanel extends VerticalPanel { sshKeyLoadingBusy.setBusy(false); } }); - } else { - sshKeyTable.getDataProvider().getList().clear(); } } } diff --git a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages.java b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages.java index 5b570ef91df..b75c6d6d030 100755 --- a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages.java +++ b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages.java @@ -55,4 +55,10 @@ com.sap.sse.gwt.adminconsole.StringMessages { String youHaveToProvideAPositiveNumberOfInstancesToLaunch(); String youHaveToProvideANonNegativePriority(); String youHaveToProvideANonNegativeNumberOfVotes(); + String mfaTokenCode(); + String login(); + String invalidCredentialsNoSessionCreated(String message); + String loggedInSuccessfully(); + String logout(); + String loggedOutSuccessfully(); } diff --git a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages.properties b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages.properties index 00910bc8c10..3f9f2dcd109 100755 --- a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages.properties +++ b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages.properties @@ -44,3 +44,9 @@ instanceType=Instance Type youHaveToProvideAPositiveNumberOfInstancesToLaunch=You have to provide a positive number of instances to launch. youHaveToProvideANonNegativePriority=You have to provide a non-negative priority. youHaveToProvideANonNegativeNumberOfVotes=You have to provide a non-negative number of votes. +mfaTokenCode=MFA Token Code +login=Login +invalidCredentialsNoSessionCreated=Invalid credentials. No session created: {0} +loggedInSuccessfully=Logged in successfully. +logout=Logout +loggedOutSuccessfully=Logged out successfully. \ No newline at end of file diff --git a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages_de.properties b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages_de.properties index a8941f13f0a..11b3cfde15a 100755 --- a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages_de.properties +++ b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages_de.properties @@ -43,4 +43,10 @@ votes=Stimmen instanceType=Instanz-Typ youHaveToProvideAPositiveNumberOfInstancesToLaunch=Die Anzahl der zu startenden Instanzen muss größer 0 sein. youHaveToProvideANonNegativePriority=Die Priorität darf nicht negativ sein. -youHaveToProvideANonNegativeNumberOfVotes=Die Stimmenanzahl darf nicht negativ sein. \ No newline at end of file +youHaveToProvideANonNegativeNumberOfVotes=Die Stimmenanzahl darf nicht negativ sein. +mfaTokenCode=MFA Token Code +login=Anmelden +invalidCredentialsNoSessionCreated=Ungültige Anmeldedaten. Es wurde keine Sitzung erstellt: {0} +loggedInSuccessfully=Anmeldung erfolgreich. +logout=Abmelden +loggedOutSuccessfully=Abmeldung erfolgreich durchgeführt. \ No newline at end of file diff --git a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/impl/Activator.java b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/impl/Activator.java index cd9ce38658e..817e914ba8a 100755 --- a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/impl/Activator.java +++ b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/impl/Activator.java @@ -1,5 +1,7 @@ package com.sap.sailing.landscape.ui.impl; +import java.util.Hashtable; + import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; @@ -8,14 +10,18 @@ import com.sap.sse.security.interfaces.PreferenceConverter; import com.sap.sse.security.util.GenericJSONPreferenceConverter; public class Activator implements BundleActivator { + public static final String USER_PREFERENCE_FOR_SESSION_TOKEN = "___aws.session.token___"; + private static BundleContext context; @Override public void start(BundleContext context) throws Exception { Activator.context = context; + final Hashtable properties = new Hashtable<>(); + properties.put(PreferenceConverter.KEY_PARAMETER_NAME, USER_PREFERENCE_FOR_SESSION_TOKEN); context.registerService(PreferenceConverter.class, new GenericJSONPreferenceConverter<>(() -> new AwsSessionCredentialsFromUserPreference()), - /* properties */ null); + properties); } @Override diff --git a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/server/LandscapeManagementWriteServiceImpl.java b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/server/LandscapeManagementWriteServiceImpl.java index db17d01e08c..dd95baefe1f 100755 --- a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/server/LandscapeManagementWriteServiceImpl.java +++ b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/server/LandscapeManagementWriteServiceImpl.java @@ -56,8 +56,6 @@ public class LandscapeManagementWriteServiceImpl extends ResultCachingProxiedRem private final FullyInitializedReplicableTracker securityServiceTracker; - private static final String USER_PREFERENCE_FOR_SESSION_TOKEN = "___aws.session.token___"; - public > LandscapeManagementWriteServiceImpl() { BundleContext context = Activator.getContext(); @@ -82,10 +80,10 @@ public class LandscapeManagementWriteServiceImpl extends ResultCachingProxiedRem final AwsSessionCredentialsWithExpiry result; checkLandscapeManageAwsPermission(); final AwsSessionCredentialsFromUserPreference credentialsPreferences = getSecurityService().getPreferenceObject( - getSecurityService().getCurrentUser().getName(), USER_PREFERENCE_FOR_SESSION_TOKEN); + getSecurityService().getCurrentUser().getName(), Activator.USER_PREFERENCE_FOR_SESSION_TOKEN); if (credentialsPreferences != null) { final AwsSessionCredentialsWithExpiry credentials = credentialsPreferences.getAwsSessionCredentialsWithExpiry(); - if (credentials.getExpiration().after(TimePoint.now())) { + if (credentials.getExpiration().before(TimePoint.now())) { result = null; } else { result = credentials; @@ -105,13 +103,13 @@ public class LandscapeManagementWriteServiceImpl extends ResultCachingProxiedRem @Override public void createMfaSessionCredentials(String awsAccessKey, String awsSecret, String mfaTokenCode) { checkLandscapeManageAwsPermission(); - final Credentials credentials = getLandscape(awsAccessKey, awsSecret).getMfaSessionCredentials(mfaTokenCode); + final Credentials credentials = AwsLandscape.obtain(awsAccessKey, awsSecret).getMfaSessionCredentials(mfaTokenCode); final AwsSessionCredentialsWithExpiryImpl result = new AwsSessionCredentialsWithExpiryImpl( credentials.accessKeyId(), credentials.secretAccessKey(), credentials.sessionToken(), TimePoint.of(credentials.expiration().toEpochMilli())); final AwsSessionCredentialsFromUserPreference credentialsPreferences = new AwsSessionCredentialsFromUserPreference(result); getSecurityService().setPreferenceObject( - getSecurityService().getCurrentUser().getName(), USER_PREFERENCE_FOR_SESSION_TOKEN, credentialsPreferences); + getSecurityService().getCurrentUser().getName(), Activator.USER_PREFERENCE_FOR_SESSION_TOKEN, credentialsPreferences); } /** @@ -122,7 +120,7 @@ public class LandscapeManagementWriteServiceImpl extends ResultCachingProxiedRem @Override public void clearSessionCredentials() { checkLandscapeManageAwsPermission(); - getSecurityService().unsetPreference(getSecurityService().getCurrentUser().getName(), USER_PREFERENCE_FOR_SESSION_TOKEN); + getSecurityService().unsetPreference(getSecurityService().getCurrentUser().getName(), Activator.USER_PREFERENCE_FOR_SESSION_TOKEN); } @Override @@ -151,10 +149,10 @@ public class LandscapeManagementWriteServiceImpl extends ResultCachingProxiedRem } @Override - public ArrayList getMongoEndpoints(String awsAccessKey, String awsSecret, String region) { + public ArrayList getMongoEndpoints(String region) { checkLandscapeManageAwsPermission(); final ArrayList result = new ArrayList<>(); - for (final MongoEndpoint mongoEndpoint : getLandscape(awsAccessKey, awsSecret).getMongoEndpoints(new AwsRegion(region))) { + for (final MongoEndpoint mongoEndpoint : getLandscape().getMongoEndpoints(new AwsRegion(region))) { final MongoEndpointDTO dto; if (mongoEndpoint.isReplicaSet()) { final MongoReplicaSet replicaSet = mongoEndpoint.asMongoReplicaSet(); @@ -172,44 +170,44 @@ public class LandscapeManagementWriteServiceImpl extends ResultCachingProxiedRem return result; } - private AwsLandscape getLandscape(String awsAccessKey, String awsSecret) { + private AwsLandscape getLandscape() { final String keyId; final String secret; - final Optional sessionToken; + final String sessionToken; final AwsSessionCredentialsWithExpiry sessionCredentials = getSessionCredentials(); + final AwsLandscape result; if (sessionCredentials != null) { keyId = sessionCredentials.getAccessKeyId(); secret = sessionCredentials.getSecretAccessKey(); - sessionToken = Optional.of(sessionCredentials.getSessionToken()); + sessionToken = sessionCredentials.getSessionToken(); + result = AwsLandscape.obtain(keyId, secret, sessionToken); } else { - keyId = awsAccessKey; - secret = awsSecret; - sessionToken = Optional.empty(); + result = null; } - return AwsLandscape.obtain(keyId, secret, sessionToken); + return result; } @Override - public MongoEndpointDTO getMongoEndpoint(String awsAccessKey, String awsSecret, String region, String replicaSetName) { - return getMongoEndpoints(awsAccessKey, awsSecret, region).stream().filter(mep->Util.equalsWithNull(mep.getReplicaSetName(), replicaSetName)).findAny().orElse(null); + public MongoEndpointDTO getMongoEndpoint(String region, String replicaSetName) { + return getMongoEndpoints(region).stream().filter(mep->Util.equalsWithNull(mep.getReplicaSetName(), replicaSetName)).findAny().orElse(null); } @Override - public SSHKeyPairDTO generateSshKeyPair(String awsAccessKey, String awsSecret, String regionId, String keyName, String privateKeyEncryptionPassphrase) { + public SSHKeyPairDTO generateSshKeyPair(String regionId, String keyName, String privateKeyEncryptionPassphrase) { final Subject subject = SecurityUtils.getSubject(); final SSHKeyPair dummyKeyPairForSecurityCheck = new SSHKeyPair(regionId, subject.getPrincipal().toString(), TimePoint.now(), keyName, /* publicKey */ null, /* encryptedPrivateKey */ null); final SSHKeyPair keyPair = getSecurityService().setOwnershipCheckPermissionForObjectCreationAndRevertOnError(dummyKeyPairForSecurityCheck.getPermissionType(), dummyKeyPairForSecurityCheck.getIdentifier().getTypeRelativeObjectIdentifier(), keyName, ()->{ - return getLandscape(awsAccessKey, awsSecret) + return getLandscape() .createKeyPair(new AwsRegion(regionId), keyName, privateKeyEncryptionPassphrase.getBytes()); }); return convertToSSHKeyPairDTO(keyPair); } @Override - public SSHKeyPairDTO addSshKeyPair(String awsAccessKey, String awsSecret, String regionId, String keyName, + public SSHKeyPairDTO addSshKeyPair(String regionId, String keyName, String publicKey, String encryptedPrivateKey) throws JSchException { final Subject subject = SecurityUtils.getSubject(); final SSHKeyPair dummyKeyPairForSecurityCheck = new SSHKeyPair(regionId, subject.getPrincipal().toString(), @@ -217,7 +215,7 @@ public class LandscapeManagementWriteServiceImpl extends ResultCachingProxiedRem final SSHKeyPair keyPair = getSecurityService().setOwnershipCheckPermissionForObjectCreationAndRevertOnError(dummyKeyPairForSecurityCheck.getPermissionType(), dummyKeyPairForSecurityCheck.getIdentifier().getTypeRelativeObjectIdentifier(), keyName, ()->{ - return getLandscape(awsAccessKey, awsSecret) + return getLandscape() .importKeyPair(new AwsRegion(regionId), publicKey.getBytes(), encryptedPrivateKey.getBytes(), keyName); }); return convertToSSHKeyPairDTO(keyPair); @@ -230,9 +228,9 @@ public class LandscapeManagementWriteServiceImpl extends ResultCachingProxiedRem } @Override - public ArrayList getSshKeys(String awsAccessKey, String awsSecret, String regionId) { + public ArrayList getSshKeys(String regionId) { final ArrayList result = new ArrayList<>(); - final AwsLandscape landscape = getLandscape(awsAccessKey, awsSecret); + final AwsLandscape landscape = getLandscape(); final AwsRegion region = new AwsRegion(regionId); for (final KeyPairInfo keyPairInfo : landscape.getAllKeyPairInfos(region)) { final SSHKeyPair key = landscape.getSSHKeyPair(region, keyPairInfo.keyName()); @@ -246,9 +244,9 @@ public class LandscapeManagementWriteServiceImpl extends ResultCachingProxiedRem } @Override - public void removeSshKey(String awsAccessKey, String awsSecret, SSHKeyPairDTO keyPair) { + public void removeSshKey(SSHKeyPairDTO keyPair) { getSecurityService().checkPermissionAndDeleteOwnershipForObjectRemoval(keyPair, - ()->getLandscape(awsAccessKey, awsSecret).deleteKeyPair(new AwsRegion(keyPair.getRegionId()), keyPair.getName())); + ()->getLandscape().deleteKeyPair(new AwsRegion(keyPair.getRegionId()), keyPair.getName())); } @Override @@ -268,11 +266,11 @@ public class LandscapeManagementWriteServiceImpl extends ResultCachingProxiedRem } @Override - public ArrayList getAmazonMachineImages(String awsAccessKey, String awsSecret, String region) { + public ArrayList getAmazonMachineImages(String region) { checkLandscapeManageAwsPermission(); final ArrayList result = new ArrayList<>(); final AwsRegion awsRegion = new AwsRegion(region); - final AwsLandscape landscape = AwsLandscape.obtain(awsAccessKey, awsSecret, /* sessionToken */ Optional.empty()); + final AwsLandscape landscape = getLandscape(); for (final String imageType : landscape.getMachineImageTypes(awsRegion)) { for (final AmazonMachineImage machineImage : landscape.getAllImagesWithType(awsRegion, imageType)) { final AmazonMachineImageDTO dto = new AmazonMachineImageDTO(machineImage.getId(), @@ -285,17 +283,17 @@ public class LandscapeManagementWriteServiceImpl extends ResultCachingProxiedRem } @Override - public void removeAmazonMachineImage(String awsAccessKey, String awsSecret, String region, String machineImageId) { + public void removeAmazonMachineImage(String region, String machineImageId) { checkLandscapeManageAwsPermission(); - final AwsLandscape landscape = AwsLandscape.obtain(awsAccessKey, awsSecret, /* sessionToken */ Optional.empty()); + final AwsLandscape landscape = getLandscape(); final AmazonMachineImage ami = landscape.getImage(new AwsRegion(region), machineImageId); ami.delete(); } @Override - public AmazonMachineImageDTO upgradeAmazonMachineImage(String awsAccessKey, String awsSecret, String region, String machineImageId) throws Exception { + public AmazonMachineImageDTO upgradeAmazonMachineImage(String region, String machineImageId) throws Exception { checkLandscapeManageAwsPermission(); - final AwsLandscape landscape = AwsLandscape.obtain(awsAccessKey, awsSecret, /* sessionToken */ Optional.empty()); + final AwsLandscape landscape = getLandscape(); final AwsRegion awsRegion = new AwsRegion(region); final AmazonMachineImage ami = landscape.getImage(awsRegion, machineImageId); final UpgradeAmi.Builder> upgradeAmiBuilder = UpgradeAmi.builder(); @@ -311,11 +309,11 @@ public class LandscapeManagementWriteServiceImpl extends ResultCachingProxiedRem } @Override - public void scaleMongo(String awsAccessKey, String awsSecret, String regionId, MongoScalingInstructionsDTO mongoScalingInstructions) throws Exception { + public void scaleMongo(String regionId, MongoScalingInstructionsDTO mongoScalingInstructions) throws Exception { if (mongoScalingInstructions.getReplicaSetName() == null) { throw new IllegalArgumentException("Can only scale MongoDB Replica Sets, not standalone instances"); } - final AwsLandscape landscape = AwsLandscape.obtain(awsAccessKey, awsSecret, /* sessionToken */ Optional.empty()); + final AwsLandscape landscape = getLandscape(); final AwsRegion region = new AwsRegion(regionId); for (int i=0; i startMongoProcessBuilder = StartMongoDBServer.builder(); diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy OSX).launch b/java/com.sap.sailing.server/SailingServer (No Proxy OSX).launch index 8d39f75b496..9da9ba00756 100755 --- a/java/com.sap.sailing.server/SailingServer (No Proxy OSX).launch +++ b/java/com.sap.sailing.server/SailingServer (No Proxy OSX).launch @@ -1,254 +1,246 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + - - - - - - - - - - - - - - - - - - - + + + + - - - - - - - - - - - + + + + + + + + + + + + + + + + - + + + - - - - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + - - - - - - - - - - - - - - - - + + + - + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy).launch b/java/com.sap.sailing.server/SailingServer (No Proxy).launch index 89acb7fa42c..8dd1f651402 100755 --- a/java/com.sap.sailing.server/SailingServer (No Proxy).launch +++ b/java/com.sap.sailing.server/SailingServer (No Proxy).launch @@ -140,6 +140,7 @@ + diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, Axel).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, Axel).launch index 86758524497..a0cf274e6a7 100644 --- a/java/com.sap.sailing.server/SailingServer (No Proxy, Axel).launch +++ b/java/com.sap.sailing.server/SailingServer (No Proxy, Axel).launch @@ -1,256 +1,248 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + - - - - - - - - - - - - - - - - - - - + + + + - - - - - - - - - - - + + + + + + + + + + + + + + + + - + + + - - - - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + - - - - - - - - - - - - - - - - + + + - + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, Cached MTB).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, Cached MTB).launch index b118ae3d6b1..12b179d1f48 100755 --- a/java/com.sap.sailing.server/SailingServer (No Proxy, Cached MTB).launch +++ b/java/com.sap.sailing.server/SailingServer (No Proxy, Cached MTB).launch @@ -1,253 +1,245 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + - - - - - - - - - - - - - - - - - - - + + + + - - - - - - - - - - - + + + + + + + + + + + + + + + + - + + + - - - - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + - - - - - - - - - - - - - - - - + + + - + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, Igtimi Local Test).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, Igtimi Local Test).launch index 6fa3221d96e..f78e19c8d34 100755 --- a/java/com.sap.sailing.server/SailingServer (No Proxy, Igtimi Local Test).launch +++ b/java/com.sap.sailing.server/SailingServer (No Proxy, Igtimi Local Test).launch @@ -1,256 +1,248 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + - - - - - - - - - - - - - - - - - - - + + + + - - - - - - - - - - - + + + + + + + + + + + + + + + + - + + + - - - - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + - - - - - - - - - - - - - - - - + + + - + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, Java11 GENERATED).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, Java11 GENERATED).launch index 5e27e5bbb66..32139f9a339 100644 --- a/java/com.sap.sailing.server/SailingServer (No Proxy, Java11 GENERATED).launch +++ b/java/com.sap.sailing.server/SailingServer (No Proxy, Java11 GENERATED).launch @@ -15,10 +15,6 @@ - - - - @@ -33,221 +29,217 @@ - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + - - - - - - - - - - - - - - - - - - - + + + + - - - - - - - - - - + + + + + + + + + + + + + + + - + + + - - - - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + - - - - - - - - - - - - - - - - + + + - + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, Java11).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, Java11).launch index 282e4c65b99..51215f7168f 100755 --- a/java/com.sap.sailing.server/SailingServer (No Proxy, Java11).launch +++ b/java/com.sap.sailing.server/SailingServer (No Proxy, Java11).launch @@ -1,256 +1,248 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + - - - - - - - - - - - - - - - - - - - + + + + - - - - - - - - - - - + + + + + + + + + + + + + + + + - + + + - - - - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + - - - - - - - - - - - - - - - - + + + - + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, Java11, JFR Recording).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, Java11, JFR Recording).launch index 95f4dcbafa3..5422a7f8119 100755 --- a/java/com.sap.sailing.server/SailingServer (No Proxy, Java11, JFR Recording).launch +++ b/java/com.sap.sailing.server/SailingServer (No Proxy, Java11, JFR Recording).launch @@ -1,256 +1,248 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + - - - - - - - - - - - - - - - - - - - + + + + - - - - - - - - - - - + + + + + + + + + + + + + + + + - + + + - - - - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + - - - - - - - - - - - - - - - - + + + - + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, Cached MTB).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, Cached MTB).launch index 021ec7ea4fe..d1ed3178528 100755 --- a/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, Cached MTB).launch +++ b/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, Cached MTB).launch @@ -1,248 +1,240 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + - - - - - - - - - - - - - - - - - - - + + + + - - - - - - - - - - - + + + + + + + + + + + + + + + + - + + + - - - - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + - - - - - - - - - - - - - - - - + + + - + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, Remote Debug SAP VM).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, Remote Debug SAP VM).launch index 0b9a81d3d18..64d26dc7c8b 100755 --- a/java/com.sap.sailing.server/SailingServer (No Proxy, Remote Debug SAP VM).launch +++ b/java/com.sap.sailing.server/SailingServer (No Proxy, Remote Debug SAP VM).launch @@ -1,247 +1,239 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + - - - - - - - - - - - - - - - - - - - + + + + - - - - - - - - - - - + + + + + + + + + + + + + + + + - + + + - - - - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + - - - - - - - - - - - - - - - - + + + - + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, bundesliga2-2017 DB).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, bundesliga2-2017 DB).launch index cbc2aad1b7c..b243f25fc5e 100755 --- a/java/com.sap.sailing.server/SailingServer (No Proxy, bundesliga2-2017 DB).launch +++ b/java/com.sap.sailing.server/SailingServer (No Proxy, bundesliga2-2017 DB).launch @@ -1,256 +1,248 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + - - - - - - - - - - - - - - - - - - - + + + + - - - - - - - - - - - + + + + + + + + + + + + + + + + - + + + - - - - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + - - - - - - - - - - - - - - - - + + + - + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, debranding active).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, debranding active).launch index b17daf95712..306699b64fa 100755 --- a/java/com.sap.sailing.server/SailingServer (No Proxy, debranding active).launch +++ b/java/com.sap.sailing.server/SailingServer (No Proxy, debranding active).launch @@ -1,256 +1,248 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + - - - - - - - - - - - - - - - - - - - + + + + - - - - - - - - - - - + + + + + + + + + + + + + + + + - + + + - - - - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + - - - - - - - - - - - - - - - - + + + - + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, winddb Axel).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, winddb Axel).launch index d5003741725..35b6d25f4fd 100644 --- a/java/com.sap.sailing.server/SailingServer (No Proxy, winddb Axel).launch +++ b/java/com.sap.sailing.server/SailingServer (No Proxy, winddb Axel).launch @@ -1,253 +1,245 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + - - - - - - - - - - - - - - - - - - - + + + + - - - - - - - - - - - + + + + + + + + + + + + + + + + - + + + - - - - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + - - - - - - - - - - - - - - - - + + + - + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, winddbTest Axel).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, winddbTest Axel).launch index 4294e9b4afe..c934f54779b 100755 --- a/java/com.sap.sailing.server/SailingServer (No Proxy, winddbTest Axel).launch +++ b/java/com.sap.sailing.server/SailingServer (No Proxy, winddbTest Axel).launch @@ -1,255 +1,246 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + - - - - - - - - - - - - - - - - - - - + + + + - - - - - - - - - - - + + + + + + + + + + + + + + + + - + + + - - - - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + - - - - - - - - - - - - - - - - + + + - + + + + + + + + + + + + + + + + + + + - - + + + + - - - - + + + + diff --git a/java/com.sap.sailing.targetplatform/definitions/race-analysis-p2-remote.target b/java/com.sap.sailing.targetplatform/definitions/race-analysis-p2-remote.target index 818475aa519..132f523f162 100755 --- a/java/com.sap.sailing.targetplatform/definitions/race-analysis-p2-remote.target +++ b/java/com.sap.sailing.targetplatform/definitions/race-analysis-p2-remote.target @@ -108,7 +108,7 @@ - + diff --git a/java/com.sap.sse.datamining.annotations/src/com/sap/sse/datamining/annotations/Connector.java b/java/com.sap.sse.datamining.annotations/src/com/sap/sse/datamining/annotations/Connector.java index 6a325ecdd89..2b93b1de9b6 100644 --- a/java/com.sap.sse.datamining.annotations/src/com/sap/sse/datamining/annotations/Connector.java +++ b/java/com.sap.sse.datamining.annotations/src/com/sap/sse/datamining/annotations/Connector.java @@ -43,5 +43,4 @@ public @interface Connector { * If false, the connection won't be used to find {@link Statistic Statistics}. */ public boolean scanForStatistics() default true; - } diff --git a/java/com.sap.sse.landscape.aws/src/com/sap/sse/landscape/aws/AwsLandscape.java b/java/com.sap.sse.landscape.aws/src/com/sap/sse/landscape/aws/AwsLandscape.java index ef9a32c237f..6f88337a27a 100755 --- a/java/com.sap.sse.landscape.aws/src/com/sap/sse/landscape/aws/AwsLandscape.java +++ b/java/com.sap.sse.landscape.aws/src/com/sap/sse/landscape/aws/AwsLandscape.java @@ -131,14 +131,26 @@ public interface AwsLandscape extends Landscape { } /** - * Based on an explicit AWS access key ID and the secret access key, this method returns a landscape object which - * internally has access to the clients for the underlying AWS landscape, such as an EC2 client, a Route53 client, - * etc. + * Based on an explicit AWS access key ID and the secret access key, this method returns a landscape object, but not + * multi factor-authenticated (MFA). Can be used for operations not requiring MFA, such as obtaining an MFA-authenticated + * version of the landscape. */ static > - AwsLandscape obtain(String accessKey, String secret, Optional mfaTokenCode) { - final AwsLandscape result = new AwsLandscapeImpl<>(Activator.getInstance().getLandscapeState(), accessKey, secret, mfaTokenCode); + AwsLandscape obtain(String accessKey, String secret) { + final AwsLandscape result = new AwsLandscapeImpl<>(Activator.getInstance().getLandscapeState(), accessKey, secret); + return result; + } + + /** + * Based on an explicit AWS access key ID, the secret access key, and an MFA token code, this method returns a + * landscape object which internally has access to the clients for the underlying AWS landscape, such as an EC2 + * client, a Route53 client, etc. + */ + static > + AwsLandscape obtain(String accessKey, String secret, String sessionToken) { + final AwsLandscape result = new AwsLandscapeImpl<>(Activator.getInstance().getLandscapeState(), accessKey, secret, sessionToken); return result; } diff --git a/java/com.sap.sse.landscape.aws/src/com/sap/sse/landscape/aws/impl/AwsLandscapeImpl.java b/java/com.sap.sse.landscape.aws/src/com/sap/sse/landscape/aws/impl/AwsLandscapeImpl.java index 4a4f5883782..3357fbf07aa 100755 --- a/java/com.sap.sse.landscape.aws/src/com/sap/sse/landscape/aws/impl/AwsLandscapeImpl.java +++ b/java/com.sap.sse.landscape.aws/src/com/sap/sse/landscape/aws/impl/AwsLandscapeImpl.java @@ -125,6 +125,8 @@ import software.amazon.awssdk.services.elasticloadbalancingv2.model.TargetGroupA import software.amazon.awssdk.services.elasticloadbalancingv2.model.TargetGroupTuple; import software.amazon.awssdk.services.elasticloadbalancingv2.model.TargetHealth; import software.amazon.awssdk.services.elasticloadbalancingv2.model.TargetTypeEnum; +import software.amazon.awssdk.services.iam.IamClient; +import software.amazon.awssdk.services.iam.model.MFADevice; import software.amazon.awssdk.services.route53.Route53Client; import software.amazon.awssdk.services.route53.model.Change; import software.amazon.awssdk.services.route53.model.ChangeAction; @@ -159,20 +161,24 @@ public class AwsLandscapeImpl implements AwsLandscape public AwsLandscapeImpl(AwsLandscapeState awsLandscapeState) { this(awsLandscapeState, - System.getProperty(ACCESS_KEY_ID_SYSTEM_PROPERTY_NAME), System.getProperty(SECRET_ACCESS_KEY_SYSTEM_PROPERTY_NAME), Optional.empty()); + System.getProperty(ACCESS_KEY_ID_SYSTEM_PROPERTY_NAME), System.getProperty(SECRET_ACCESS_KEY_SYSTEM_PROPERTY_NAME)); } - public AwsLandscapeImpl(AwsLandscapeState awsLandscapeState, String accessKeyId, String secretAccessKey, Optional mfaTokenCode) { - this(accessKeyId, secretAccessKey, mfaTokenCode, + public AwsLandscapeImpl(AwsLandscapeState awsLandscapeState, String accessKeyId, String secretAccessKey) { + this(awsLandscapeState, accessKeyId, secretAccessKey, /* no session token */ null); + } + + public AwsLandscapeImpl(AwsLandscapeState awsLandscapeState, String accessKeyId, String secretAccessKey, String sessionToken) { + this(accessKeyId, secretAccessKey, sessionToken, // by using MongoDBService.INSTANCE the default test configuration will be used if nothing else is configured PersistenceFactory.INSTANCE.getDomainObjectFactory(MongoDBService.INSTANCE), PersistenceFactory.INSTANCE.getMongoObjectFactory(MongoDBService.INSTANCE), awsLandscapeState); } public AwsLandscapeImpl(String accessKeyId, String secretAccessKey, - Optional sessionToken, DomainObjectFactory domainObjectFactory, MongoObjectFactory mongoObjectFactory, AwsLandscapeState landscapeState) { + String sessionToken, DomainObjectFactory domainObjectFactory, MongoObjectFactory mongoObjectFactory, AwsLandscapeState landscapeState) { this.accessKeyId = accessKeyId; this.secretAccessKey = secretAccessKey; - this.sessionToken = sessionToken; + this.sessionToken = Optional.ofNullable(sessionToken); this.globalRegion = new AwsRegion(Region.AWS_GLOBAL); this.landscapeState = landscapeState; } @@ -593,8 +599,16 @@ public class AwsLandscapeImpl implements AwsLandscape @Override public Credentials getMfaSessionCredentials(String nonEmptyMfaTokenCode) { - return StsClient.builder().credentialsProvider(()->AwsBasicCredentials.create(accessKeyId, secretAccessKey)).build() - .getSessionToken(b->b.tokenCode(nonEmptyMfaTokenCode)).credentials(); + final AwsBasicCredentials basicCredentials = AwsBasicCredentials.create(accessKeyId, secretAccessKey); + final List mfaDevices = IamClient.builder().region(Region.AWS_GLOBAL).credentialsProvider(()->basicCredentials).build() + .listMFADevices().mfaDevices(); + logger.info("Found the following MFA devices: "+Util.joinStrings(", ", Util.map(mfaDevices, d->d.serialNumber()))); + final String serialNumberOfMfaDevice = mfaDevices.iterator().next().serialNumber(); + logger.info("Found MFA device "+serialNumberOfMfaDevice+"; using MFA token code "+nonEmptyMfaTokenCode); + final Credentials result = StsClient.builder().credentialsProvider(()->basicCredentials).build() + .getSessionToken(b->b.tokenCode(nonEmptyMfaTokenCode).serialNumber(serialNumberOfMfaDevice)).credentials(); + logger.info("Produced valid MFA session credentials for access key ID "+result.accessKeyId()); + return result; } @Override