/************************************************************************************* * Copyright (c) 2014 Red Hat, Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * JBoss by Red Hat - Initial implementation. ************************************************************************************/ package org.jboss.tools.runtime.ui.internal.wizard.workflow; import java.lang.reflect.InvocationTargetException; import java.util.List; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.FormLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Link; import org.jboss.tools.foundation.core.credentials.CredentialService; import org.jboss.tools.foundation.ui.credentials.ChooseCredentialComposite; import org.jboss.tools.foundation.ui.credentials.ICredentialCompositeListener; import org.jboss.tools.foundation.ui.util.BrowserUtility; import org.jboss.tools.foundation.ui.util.FormDataUtility; import org.jboss.tools.foundation.ui.xpl.taskwizard.IWizardHandle; import org.jboss.tools.foundation.ui.xpl.taskwizard.WizardFragment; import org.jboss.tools.runtime.core.model.DownloadRuntime; import org.jboss.tools.runtime.ui.DownloadRuntimeMessages; import org.jboss.tools.runtime.ui.RuntimeUIActivator; import org.jboss.tools.runtime.ui.wizard.DownloadRuntimesTaskWizard; /** * This page will request credentials from the user to be used during the * download of the file. It is customized for urls that are part of the download * manager api, but will work for other urls that simply redirect * to a file. * * It will first make a request without any xml headers. In the event * of an error condition, it will try to use the xml header to know * what the next step is, for example, signing the terms and conditions. */ public class DownloadManagerCredentialsFragment extends WizardFragment { /** * In the event of a workflow error condition (more steps to complete), * the result of the api call will be stored in the task manager under this key. */ public static final String WORKFLOW_NEXT_STEP_KEY = "WORKFLOW_NEXT_STEP_KEY"; /** * The singup url for jboss.org */ private String JBOSS_ORG_SIGNUP_URL = "https://community.jboss.org/register.jspa"; //$NON-NLS-1$ private static final String DOWNLOAD_RUNTIME_SECTION = "downloadRuntimeSection"; //$NON-NLS-1$ private IDialogSettings downloadRuntimeSection; private IWizardHandle handle; private int headerResponse = -1; private WizardFragment nextWorkflowFragment = null; private ChooseCredentialComposite chooseCredentialComposite; public DownloadManagerCredentialsFragment() { IDialogSettings dialogSettings = RuntimeUIActivator.getDefault().getDialogSettings(); downloadRuntimeSection = dialogSettings.getSection(DOWNLOAD_RUNTIME_SECTION); if (downloadRuntimeSection == null) { downloadRuntimeSection = dialogSettings.addNewSection(DOWNLOAD_RUNTIME_SECTION); } } @Override public boolean hasComposite() { return true; } @Override protected void createChildFragments(List<WizardFragment> list) { if( nextWorkflowFragment != null ) { list.add(nextWorkflowFragment); } } @Override public void enter() { } @Override public Composite createComposite(Composite parent, IWizardHandle handle) { this.handle = handle; getPage().setTitle(DownloadRuntimeMessages.CredentialsFragmentTitle); getPage().setDescription(DownloadRuntimeMessages.CredentialsFragmentDescription); Composite contents = new Composite(parent, SWT.NONE); GridData gd = new GridData(GridData.FILL_BOTH); contents.setLayoutData(gd); contents.setLayout(new FormLayout()); Link l = new Link(contents, SWT.WRAP); l.setText(DownloadRuntimeMessages.CredentialsFragmentInstructions); l.setLayoutData(FormDataUtility.createFormData2(0, 5, null, 0, 0, 5, 0,400)); l.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { createJBossOrgAccount(); } }); chooseCredentialComposite = createCredentialComposite(contents); chooseCredentialComposite.setLayoutData(FormDataUtility.createFormData2(l, 5, null, 0, 0, 5, 100, -5)); readFromCredentialComposite(true); return contents; } private ChooseCredentialComposite createCredentialComposite(Composite parent) { final ChooseCredentialComposite comp = new ChooseCredentialComposite( parent, new String[]{CredentialService.JBOSS_ORG, CredentialService.REDHAT_ACCESS}, null, ChooseCredentialComposite.STYLE_PASSWORD_OVERRIDE); comp.addCredentialListener(new ICredentialCompositeListener() { public void credentialsChanged() { readFromCredentialComposite(true); } }); return comp; } private void readFromCredentialComposite(boolean validate) { getTaskModel().putObject(DownloadRuntimesTaskWizard.USERNAME_KEY, chooseCredentialComposite.getUser()); getTaskModel().putObject(DownloadRuntimesTaskWizard.PASSWORD_KEY, chooseCredentialComposite.getPassword()); if( validate ) validateFragment(); } protected void createJBossOrgAccount() { new BrowserUtility().checkedCreateExternalBrowser(JBOSS_ORG_SIGNUP_URL, RuntimeUIActivator.PLUGIN_ID, RuntimeUIActivator.getDefault().getLog()); } protected void validateFragment() { String tempName = (String)getTaskModel().getObject(DownloadRuntimesTaskWizard.USERNAME_KEY); String tempPass = (String)getTaskModel().getObject(DownloadRuntimesTaskWizard.PASSWORD_KEY); boolean nameEmpty = tempName == null || tempName.trim().length() == 0; boolean passEmpty = tempPass == null || tempPass.trim().length() == 0; setComplete(!nameEmpty && !passEmpty); headerResponse = -1; DownloadManagerCredentialsFragment.this.handle.update(); } private void validationPressed() { final String userS = (String)getTaskModel().getObject(DownloadRuntimesTaskWizard.USERNAME_KEY); final String passS = (String)getTaskModel().getObject(DownloadRuntimesTaskWizard.PASSWORD_KEY); final String[] error = new String[1]; try { handle.run(true, false, new IRunnableWithProgress() { public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { monitor.beginTask(DownloadRuntimeMessages.ValidatingCredentials, 100); monitor.worked(10); error[0] = validateCredentials(userS, passS); monitor.done(); } }); if( error[0] != null ) handle.setMessage(error[0], IWizardHandle.ERROR); else handle.setMessage(null, IWizardHandle.NONE); handle.update(); } catch(InterruptedException ie) { RuntimeUIActivator.pluginLog().logError(ie); } catch(InvocationTargetException ite) { RuntimeUIActivator.pluginLog().logError(ite); } } /** * If the URL is from download-manager/rest/jdf, then the results vary depending on whether * an xml header has been added or not. * If an XML header is NOT added to the request: * 1) invalid credentials return status 401 * 2) valid credentials but invalid workflow return 403 * 3) everything ok returns 302 redirect to the file * * If xml header is added to the request: * 1) invalid credentials return status 401 * 2) valid credentials return status 200 with xml content indicating what's missing * 3) everything ok returns 302 redirect to the file * * @param userS * @param passS * @return an error message */ private String validateCredentials(String userS, String passS) { try { int response = DownloadManagerWorkflowUtility.getWorkflowStatus(getDownloadRuntimeFromTaskModel(), userS, passS); if( response == DownloadManagerWorkflowUtility.CREDENTIALS_FAILED ) { return DownloadRuntimeMessages.CredentialsIncorrect; } else if( response == DownloadManagerWorkflowUtility.WORKFLOW_FAILED ) { String responseContent = DownloadManagerWorkflowUtility.getWorkflowResponseContent( getDownloadRuntimeFromTaskModel(), userS, passS); getTaskModel().putObject(WORKFLOW_NEXT_STEP_KEY, responseContent); nextWorkflowFragment = DownloadManagerWorkflowUtility.getNextWorkflowFragment(responseContent); if( nextWorkflowFragment == null ) { // we got a workflow error, but no fragment available. // Point the user to a hyperlink in web browser TODO return NLS.bind(DownloadRuntimeMessages.CredentialWorkflowFailed, getDownloadRuntimeFromTaskModel().getUrl()); } else { return null; } // need to find the next path } else if( response == DownloadManagerWorkflowUtility.AUTHORIZED ) { // this page is complete nextWorkflowFragment = null; return null; } } catch(Exception e) { RuntimeUIActivator.pluginLog().logError(e); return NLS.bind(DownloadRuntimeMessages.CredentialError, e.getClass().getName(), e.getMessage()); } return null; } private DownloadRuntime getDownloadRuntimeFromTaskModel() { return (DownloadRuntime)getTaskModel().getObject(DownloadRuntimesTaskWizard.DL_RUNTIME_PROP); } /** * If you must perform a long-running action when * next is pressed, return true. Otherwise false * @return */ protected boolean hasActionOnNextPressed() { return true; } /** * Perform your long-running action. * Return whether the page should be changed, * or the action has failed. * * @return */ protected boolean performNextPressedAction() { validationPressed(); String msg = handle.getMessage(); if( msg != null ) { setComplete(false); handle.update(); } return msg == null; } }