/******************************************************************************* * Copyright (c) 2015, 2016 Pivotal Software, Inc. * 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: * Pivotal Software, Inc. - initial API and implementation *******************************************************************************/ package org.springsource.ide.eclipse.commons.cloudfoundry.client.diego; import java.net.URI; import java.net.URISyntaxException; import java.util.List; import java.util.UUID; import javax.naming.OperationNotSupportedException; import org.apache.http.NameValuePair; import org.apache.http.client.utils.URIBuilder; import org.apache.http.client.utils.URLEncodedUtils; import org.cloudfoundry.client.lib.CloudCredentials; import org.cloudfoundry.client.lib.CloudFoundryException; import org.cloudfoundry.client.lib.CloudFoundryOperations; import org.cloudfoundry.client.lib.CloudOperationException; import org.cloudfoundry.client.lib.HttpProxyConfiguration; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; /** * @author Kris De Volder */ public class SshClientSupportV1 extends CfClientSideCart implements SshClientSupport { private String authorizationUrl; private String sshClientId; public SshClientSupportV1(CloudFoundryOperations client, CloudInfoV2 cloudInfo, boolean trustSelfSigned, HttpProxyConfiguration httpProxyConfiguration) { super(client, cloudInfo, trustSelfSigned, httpProxyConfiguration); this.authorizationUrl = cloudInfo.getAuthorizationUrl(); this.sshClientId = cloudInfo.getSshClientId(); } @Override public String getSshCode() { try { URIBuilder builder = new URIBuilder(authorizationUrl + "/oauth/authorize"); //$NON-NLS-1$ builder.addParameter("response_type" //$NON-NLS-1$ , "code"); //$NON-NLS-1$ builder.addParameter("grant_type", //$NON-NLS-1$ "authorization_code"); //$NON-NLS-1$ builder.addParameter("client_id", sshClientId); //$NON-NLS-1$ URI url = new URI(builder.toString()); ResponseEntity<String> response = restTemplate.getForEntity(url, String.class); HttpStatus statusCode = response.getStatusCode(); if (statusCode!=HttpStatus.FOUND) { throw new CloudFoundryException(statusCode); } String loc = response.getHeaders().getFirst("Location"); //$NON-NLS-1$ if (loc==null) { throw new CloudOperationException("No 'Location' header in redirect response"); //$NON-NLS-1$ } List<NameValuePair> qparams = URLEncodedUtils.parse(new URI(loc), "utf8"); //$NON-NLS-1$ for (NameValuePair pair : qparams) { String name = pair.getName(); if (name.equals("code")) { //$NON-NLS-1$ return pair.getValue(); } } throw new CloudOperationException("No 'code' param in redirect Location: "+loc); //$NON-NLS-1$ } catch (URISyntaxException e) { throw new CloudOperationException(e); } } @Override public SshHost getSshHost() { return cloudInfo.getSshHost(); } public static SshClientSupportV1 create(final CloudFoundryOperations client, CloudCredentials creds, HttpProxyConfiguration proxyConf, boolean selfSigned) { CloudInfoV2 cloudInfo = new CloudInfoV2( creds, client.getCloudControllerUrl(), proxyConf, selfSigned ); return new SshClientSupportV1(client, cloudInfo, selfSigned, proxyConf); } /** * When connecting an ssh client to CF the 'username' is derived from, and identifies a * specific app instance. This method formats the 'username' from an appGuid and an instance number. */ @Override public String getSshUser(UUID appGuid, int instance) { return "cf:"+appGuid+"/" + instance; } @Override public String getSshUser(String appName, int instance) throws Exception { throw new OperationNotSupportedException("Not supported in CF V1 client"); } }