/* * SoapUI, Copyright (C) 2004-2016 SmartBear Software * * Licensed under the EUPL, Version 1.1 or - as soon as they will be approved by the European Commission - subsequent * versions of the EUPL (the "Licence"); * You may not use this work except in compliance with the Licence. * You may obtain a copy of the Licence at: * * http://ec.europa.eu/idabc/eupl * * Unless required by applicable law or agreed to in writing, software distributed under the Licence is * distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the Licence for the specific language governing permissions and limitations * under the Licence. */ package com.eviware.soapui.support.editor.inspectors.auth; import com.eviware.soapui.SoapUI; import com.eviware.soapui.config.OAuth2FlowConfig; import com.eviware.soapui.impl.rest.OAuth2Profile; import com.eviware.soapui.impl.rest.actions.oauth.GetOAuthAccessTokenAction; import com.eviware.soapui.impl.wsdl.support.HelpUrls; import com.eviware.soapui.support.UISupport; import com.eviware.soapui.support.components.PropertyComponent; import com.eviware.soapui.support.components.SimpleBindingForm; import com.jgoodies.binding.PresentationModel; import com.jgoodies.binding.value.AbstractValueModel; import javax.annotation.Nonnull; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.BorderFactory; import javax.swing.ComboBoxModel; import javax.swing.DefaultComboBoxModel; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.SwingUtilities; import javax.swing.border.Border; import java.awt.Color; import java.awt.event.ActionEvent; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; public class OAuth2GetAccessTokenForm implements OAuth2AccessTokenStatusChangeListener { public static final String CLIENT_ID_TITLE = "Client Identification"; public static final String CLIENT_SECRET_TITLE = "Client Secret"; public static final String RESOURCE_OWNER_LOGIN = "Resource Owner Name"; public static final String RESOURCE_OWNER_PASSWORD = "Resource Owner Password"; public static final String AUTHORIZATION_URI_TITLE = "Authorization URI"; public static final String ACCESS_TOKEN_URI_TITLE = "Access Token URI"; public static final String REDIRECT_URI_TITLE = "Redirect URI"; public static final String SCOPE_TITLE = "Scope"; public static final String OAUTH_2_FLOW_COMBO_BOX_NAME = "OAuth2Flow"; public static final String ACCESS_TOKEN_FORM_DIALOG_NAME = "getAccessTokenFormDialog"; private static final String GET_ACCESS_TOKEN_BUTTON_NAME = "getAccessTokenButtonName"; private static final String ACCESS_TOKEN_FORM_DIALOG_TITLE = "Get Access Token"; private static final String AUTOMATION_BUTTON_TITLE = "Automation..."; private static final String GET_ACCESS_TOKEN_FORM_LAYOUT = "7dlu:none,left:pref,10dlu,left:pref,10dlu,left:MAX(112dlu;pref),7dlu"; private static final int BOARDER_SPACING = 15; private static final int NORMAL_SPACING = 10; private static final int GROUP_SPACING = 20; private static final Color CARD_BORDER_COLOR = new Color(121, 121, 121); static final ImageIcon DEFAULT_ICON = null; private OAuth2Profile profile; private JLabel accessTokenStatusText; private OAuth2AccessTokenStatusChangeManager statusChangeManager; private JDialog accessTokenDialog; private OAuth2ScriptsDesktopPanel scriptEditorPanel; public OAuth2GetAccessTokenForm(OAuth2Profile profile) { this.profile = profile; } public JDialog getComponent() { SimpleBindingForm accessTokenForm = createSimpleBindingForm(profile); statusChangeManager = new OAuth2AccessTokenStatusChangeManager(this); populateGetAccessTokenForm(accessTokenForm); statusChangeManager.register(); if (profile.getAccessTokenStatus() != OAuth2Profile.AccessTokenStatus.RETRIEVAL_CANCELED) { profile.resetAccessTokenStatusToStartingStatus(); } setOAuth2StatusFeedback(profile.getAccessTokenStatus()); accessTokenDialog = createGetAccessTokenDialog(accessTokenForm.getPanel()); return accessTokenDialog; } @Override public void onAccessTokenStatusChanged(@Nonnull OAuth2Profile.AccessTokenStatus status) { setOAuth2StatusFeedback(status); } @Nonnull @Override public OAuth2Profile getProfile() { return profile; } void release() { statusChangeManager.unregister(); } private SimpleBindingForm createSimpleBindingForm(OAuth2Profile profile) { PresentationModel presentationModel = new PresentationModel<OAuth2Profile>(profile); String columnsSpecs = GET_ACCESS_TOKEN_FORM_LAYOUT; Border border = BorderFactory.createLineBorder(CARD_BORDER_COLOR, 1); return new SimpleBindingForm(presentationModel, columnsSpecs, border); } private void populateGetAccessTokenForm(SimpleBindingForm accessTokenForm) { accessTokenForm.addSpace(BOARDER_SPACING); accessTokenForm.appendHeadingAndHelpButton("Get Access Token from the authorization server", HelpUrls.OAUTH_ACCESS_TOKEN_RETRIEVAL); accessTokenForm.addSpace(NORMAL_SPACING); JComboBox oauth2FlowComboBox = appendOAuth2ComboBox(accessTokenForm); accessTokenForm.addSpace(GROUP_SPACING); final JTextField resOwnerPassTextField = accessTokenForm.appendTextField(OAuth2Profile.RESOURCE_OWNER_LOGIN_PROPERTY, RESOURCE_OWNER_LOGIN, ""); resOwnerPassTextField.setVisible(oauth2FlowComboBox.getSelectedItem().equals(OAuth2Profile.OAuth2Flow.valueOf(OAuth2FlowConfig.RESOURCE_OWNER_PASSWORD_CREDENTIALS.toString()))); final JTextField resOwnerNameTextField = accessTokenForm.appendTextField(OAuth2Profile.RESOURCE_OWNER_PASSWORD_PROPERTY, RESOURCE_OWNER_PASSWORD, ""); resOwnerNameTextField.setVisible(oauth2FlowComboBox.getSelectedItem().equals(OAuth2Profile.OAuth2Flow.valueOf(OAuth2FlowConfig.RESOURCE_OWNER_PASSWORD_CREDENTIALS.toString()))); accessTokenForm.appendTextField(OAuth2Profile.CLIENT_ID_PROPERTY, CLIENT_ID_TITLE, ""); final JTextField clientSecretField = appendClientSecretField(accessTokenForm, getOAuth2FlowValueModel(accessTokenForm)); accessTokenForm.addSpace(GROUP_SPACING); final JTextField authUriTextField = accessTokenForm.appendTextField(OAuth2Profile.AUTHORIZATION_URI_PROPERTY, AUTHORIZATION_URI_TITLE, ""); authUriTextField.setVisible(!oauth2FlowComboBox.getSelectedItem().equals(OAuth2Profile.OAuth2Flow.valueOf(OAuth2FlowConfig.RESOURCE_OWNER_PASSWORD_CREDENTIALS.toString())) && !oauth2FlowComboBox.getSelectedItem().equals(OAuth2Profile.OAuth2Flow.valueOf(OAuth2FlowConfig.CLIENT_CREDENTIALS_GRANT.toString()))); final JTextField accessTokenUriField = appendAccessTokenUriField(accessTokenForm, getOAuth2FlowValueModel(accessTokenForm)); final JTextField redirectUriTextField = accessTokenForm.appendTextField(OAuth2Profile.REDIRECT_URI_PROPERTY, REDIRECT_URI_TITLE, ""); redirectUriTextField.setVisible(!oauth2FlowComboBox.getSelectedItem().equals(OAuth2Profile.OAuth2Flow.valueOf(OAuth2FlowConfig.RESOURCE_OWNER_PASSWORD_CREDENTIALS.toString())) && !oauth2FlowComboBox.getSelectedItem().equals(OAuth2Profile.OAuth2Flow.valueOf(OAuth2FlowConfig.CLIENT_CREDENTIALS_GRANT.toString()))); accessTokenForm.addSpace(GROUP_SPACING); accessTokenForm.appendTextField(OAuth2Profile.SCOPE_PROPERTY, SCOPE_TITLE, ""); accessTokenForm.addSpace(NORMAL_SPACING); accessTokenForm.appendComponentsInOneRow(createGetAccessTokenButton(), createAccessTokenStatusText()); accessTokenForm.appendButtonWithoutLabel(AUTOMATION_BUTTON_TITLE, new EditAutomationScriptsAction(profile)); accessTokenForm.addSpace(GROUP_SPACING); accessTokenForm.appendLabelAsLink(HelpUrls.OAUTH_ACCESS_TOKEN_FROM_SERVER, "How to get an access token from an authorization server"); accessTokenForm.addSpace(BOARDER_SPACING); oauth2FlowComboBox.addItemListener(new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { if (e.getStateChange() == ItemEvent.SELECTED) { clientSecretField.setVisible(!e.getItem().equals(OAuth2Profile.OAuth2Flow.valueOf(OAuth2FlowConfig.IMPLICIT_GRANT.toString()))); accessTokenUriField.setVisible(!e.getItem().equals(OAuth2Profile.OAuth2Flow.valueOf(OAuth2FlowConfig.IMPLICIT_GRANT.toString()))); authUriTextField.setVisible(!e.getItem().equals(OAuth2Profile.OAuth2Flow.valueOf(OAuth2FlowConfig.RESOURCE_OWNER_PASSWORD_CREDENTIALS.toString())) && !e.getItem().equals(OAuth2Profile.OAuth2Flow.valueOf(OAuth2FlowConfig.CLIENT_CREDENTIALS_GRANT.toString()))); redirectUriTextField.setVisible(!e.getItem().equals(OAuth2Profile.OAuth2Flow.valueOf(OAuth2FlowConfig.RESOURCE_OWNER_PASSWORD_CREDENTIALS.toString())) && !e.getItem().equals(OAuth2Profile.OAuth2Flow.valueOf(OAuth2FlowConfig.CLIENT_CREDENTIALS_GRANT.toString()))); resOwnerNameTextField.setVisible(e.getItem().equals(OAuth2Profile.OAuth2Flow.valueOf(OAuth2FlowConfig.RESOURCE_OWNER_PASSWORD_CREDENTIALS.toString()))); resOwnerPassTextField.setVisible(e.getItem().equals(OAuth2Profile.OAuth2Flow.valueOf(OAuth2FlowConfig.RESOURCE_OWNER_PASSWORD_CREDENTIALS.toString()))); SwingUtilities.invokeLater(new Runnable() { @Override public void run() { accessTokenDialog.pack(); } }); } } }); } private AbstractValueModel getOAuth2FlowValueModel(SimpleBindingForm accessTokenForm) { return accessTokenForm.getPresentationModel().getModel(OAuth2Profile.OAUTH2_FLOW_PROPERTY, "getOAuth2Flow", "setOAuth2Flow"); } private JComboBox appendOAuth2ComboBox(SimpleBindingForm accessTokenForm) { AbstractValueModel valueModel = getOAuth2FlowValueModel(accessTokenForm); ComboBoxModel oauth2FlowsModel = new DefaultComboBoxModel(OAuth2Profile.OAuth2Flow.values()); JComboBox oauth2FlowComboBox = accessTokenForm.appendComboBox("OAuth 2 Flow", oauth2FlowsModel, "OAuth 2 Authorization Flow", valueModel); oauth2FlowComboBox.setName(OAUTH_2_FLOW_COMBO_BOX_NAME); return oauth2FlowComboBox; } private JTextField appendClientSecretField(SimpleBindingForm accessTokenForm, AbstractValueModel valueModel) { final JTextField clientSecretField = accessTokenForm.appendTextField(OAuth2Profile.CLIENT_SECRET_PROPERTY, CLIENT_SECRET_TITLE, ""); if (valueModel.getValue() == OAuth2Profile.OAuth2Flow.IMPLICIT_GRANT) { clientSecretField.setVisible(false); } return clientSecretField; } private JTextField appendAccessTokenUriField(SimpleBindingForm accessTokenForm, AbstractValueModel valueModel) { final JTextField accessTokenUriField = accessTokenForm.appendTextField(OAuth2Profile.ACCESS_TOKEN_URI_PROPERTY, ACCESS_TOKEN_URI_TITLE, ""); if (valueModel.getValue() == OAuth2Profile.OAuth2Flow.IMPLICIT_GRANT) { accessTokenUriField.setVisible(false); } return accessTokenUriField; } private PropertyComponent createGetAccessTokenButton() { JButton getAccessTokenButton = new JButton(new GetOAuthAccessTokenAction(profile)); getAccessTokenButton.setName(GET_ACCESS_TOKEN_BUTTON_NAME); return new PropertyComponent(getAccessTokenButton); } private PropertyComponent createAccessTokenStatusText() { accessTokenStatusText = new JLabel(); return new PropertyComponent(accessTokenStatusText); } private JDialog createGetAccessTokenDialog(JPanel accessTokenFormPanel) { final JDialog accessTokenFormDialog = new JDialog(); accessTokenFormDialog.setName(ACCESS_TOKEN_FORM_DIALOG_NAME); accessTokenFormDialog.setTitle(ACCESS_TOKEN_FORM_DIALOG_TITLE); accessTokenFormDialog.setIconImages(SoapUI.getFrameIcons()); accessTokenFormDialog.setUndecorated(true); accessTokenFormDialog.getContentPane().add(accessTokenFormPanel); return accessTokenFormDialog; } private void setOAuth2StatusFeedback(OAuth2Profile.AccessTokenStatus status) { // There are no auth profile selected if (status == null) { setDefaultFeedback(); } else { switch (status) { case WAITING_FOR_AUTHORIZATION: case RECEIVED_AUTHORIZATION_CODE: setWaitingFeedback(status); break; case RETRIEVAL_CANCELED: setCanceledFeedback(status); break; case ENTERED_MANUALLY: case RETRIEVED_FROM_SERVER: default: setDefaultFeedback(); break; } } } private void setCanceledFeedback(OAuth2Profile.AccessTokenStatus status) { accessTokenStatusText.setText(status.toString()); accessTokenStatusText.setIcon(OAuth2Form.FAIL_ICON); } private void setWaitingFeedback(OAuth2Profile.AccessTokenStatus status) { accessTokenStatusText.setText(status.toString()); accessTokenStatusText.setIcon(OAuth2Form.WAIT_ICON); } private void setDefaultFeedback() { accessTokenStatusText.setText(""); accessTokenStatusText.setIcon(DEFAULT_ICON); SwingUtilities.invokeLater(new Runnable() { public void run() { closeGetAccessTokenDialog(); } }); } private void closeGetAccessTokenDialog() { if (accessTokenDialog != null) { accessTokenDialog.setVisible(false); accessTokenDialog.dispose(); } } private class EditAutomationScriptsAction extends AbstractAction { private final OAuth2Profile profile; public EditAutomationScriptsAction(OAuth2Profile profile) { putValue(Action.NAME, AUTOMATION_BUTTON_TITLE); this.profile = profile; } @Override public void actionPerformed(ActionEvent e) { closeGetAccessTokenDialog(); if (scriptEditorPanel == null) { scriptEditorPanel = new OAuth2ScriptsDesktopPanel(profile); } UISupport.showDesktopPanel(scriptEditorPanel); } } }