Skip to content
This repository was archived by the owner on Nov 28, 2022. It is now read-only.

CW Issue #2647: Initial support for template source authorization #756

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2018, 2019 IBM Corporation and others.
* Copyright (c) 2018, 2020 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
Expand Down Expand Up @@ -27,7 +27,6 @@
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.eclipse.codewind.core.internal.cli.AuthToken;
import org.json.JSONArray;
import org.json.JSONObject;

Expand Down Expand Up @@ -142,55 +141,55 @@ public static HttpResult get(URI uri) throws IOException {
return get(uri, null);
}

public static HttpResult get(URI uri, AuthToken auth) throws IOException {
public static HttpResult get(URI uri, IAuthInfo auth) throws IOException {
return sendRequest("GET", uri, auth, null);
}

public static HttpResult get(URI uri, AuthToken auth, int connectTimeoutMS, int readTimeoutMS) throws IOException {
public static HttpResult get(URI uri, IAuthInfo auth, int connectTimeoutMS, int readTimeoutMS) throws IOException {
return sendRequest("GET", uri, auth, null, connectTimeoutMS, readTimeoutMS);
}

public static HttpResult post(URI uri, AuthToken auth, JSONObject payload) throws IOException {
public static HttpResult post(URI uri, IAuthInfo auth, JSONObject payload) throws IOException {
return sendRequest("POST", uri, auth, payload, DEFAULT_CONNECT_TIMEOUT_MS, DEFAULT_READ_TIMEOUT_MS);
}

public static HttpResult post(URI uri, AuthToken auth, JSONObject payload, int readTimeoutSeconds) throws IOException {
public static HttpResult post(URI uri, IAuthInfo auth, JSONObject payload, int readTimeoutSeconds) throws IOException {
return sendRequest("POST", uri, auth, payload, DEFAULT_CONNECT_TIMEOUT_MS, readTimeoutSeconds * 1000);
}

public static HttpResult post(URI uri, AuthToken auth) throws IOException {
public static HttpResult post(URI uri, IAuthInfo auth) throws IOException {
return sendRequest("POST", uri, auth, null);
}

public static HttpResult put(URI uri, AuthToken auth) throws IOException {
public static HttpResult put(URI uri, IAuthInfo auth) throws IOException {
return sendRequest("PUT", uri, auth, null);
}

public static HttpResult put(URI uri, AuthToken auth, JSONObject payload) throws IOException {
public static HttpResult put(URI uri, IAuthInfo auth, JSONObject payload) throws IOException {
return sendRequest("PUT", uri, auth, payload, DEFAULT_CONNECT_TIMEOUT_MS, DEFAULT_READ_TIMEOUT_MS);
}

public static HttpResult put(URI uri, AuthToken auth, JSONObject payload, int readTimoutSeconds) throws IOException {
public static HttpResult put(URI uri, IAuthInfo auth, JSONObject payload, int readTimoutSeconds) throws IOException {
return sendRequest("PUT", uri, auth, payload, DEFAULT_CONNECT_TIMEOUT_MS, DEFAULT_READ_TIMEOUT_MS);
}

public static HttpResult head(URI uri, AuthToken auth) throws IOException {
public static HttpResult head(URI uri, IAuthInfo auth) throws IOException {
return sendRequest("HEAD", uri, auth, null);
}

public static HttpResult delete(URI uri, AuthToken auth) throws IOException {
public static HttpResult delete(URI uri, IAuthInfo auth) throws IOException {
return delete(uri, auth, null);
}

public static HttpResult delete(URI uri, AuthToken auth, JSONObject payload) throws IOException {
public static HttpResult delete(URI uri, IAuthInfo auth, JSONObject payload) throws IOException {
return sendRequest("DELETE", uri, auth, payload);
}

public static HttpResult sendRequest(String method, URI uri, AuthToken auth, JSONObject payload) throws IOException {
public static HttpResult sendRequest(String method, URI uri, IAuthInfo auth, JSONObject payload) throws IOException {
return sendRequest(method, uri, auth, payload, DEFAULT_CONNECT_TIMEOUT_MS, DEFAULT_READ_TIMEOUT_MS);
}

public static HttpResult sendRequest(String method, URI uri, AuthToken auth, JSONObject payload, int connectTimeoutMS, int readTimeoutMS) throws IOException {
public static HttpResult sendRequest(String method, URI uri, IAuthInfo auth, JSONObject payload, int connectTimeoutMS, int readTimeoutMS) throws IOException {
HttpURLConnection connection = null;
if (payload != null) {
Logger.log("Making a " + method + " request on " + uri + " with payload: " + payload.toString());
Expand Down Expand Up @@ -222,11 +221,11 @@ public static HttpResult sendRequest(String method, URI uri, AuthToken auth, JSO
}
}

private static void addAuthorization(HttpURLConnection connection, AuthToken auth) {
if (sslContext == null || auth == null || auth.getToken() == null || auth.getTokenType() == null || !(connection instanceof HttpsURLConnection)) {
private static void addAuthorization(HttpURLConnection connection, IAuthInfo auth) {
if (sslContext == null || auth == null || !auth.isValid() || !(connection instanceof HttpsURLConnection)) {
return;
}
connection.setRequestProperty("Authorization", auth.getTokenType() + " " + auth.getToken());
connection.setRequestProperty("Authorization", auth.getHttpAuthorization());
((HttpsURLConnection)connection).setSSLSocketFactory(sslContext.getSocketFactory());
((HttpsURLConnection)connection).setHostnameVerifier(hostnameVerifier);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*******************************************************************************
* Copyright (c) 2020 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/


package org.eclipse.codewind.core.internal;

public interface IAuthInfo {

public boolean isValid();

public String getHttpAuthorization();

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2019 IBM Corporation and others.
* Copyright (c) 2019, 2020 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
Expand All @@ -11,10 +11,11 @@

package org.eclipse.codewind.core.internal.cli;

import org.eclipse.codewind.core.internal.IAuthInfo;
import org.eclipse.codewind.core.internal.connection.JSONObjectResult;
import org.json.JSONObject;

public class AuthToken extends JSONObjectResult {
public class AuthToken extends JSONObjectResult implements IAuthInfo {

private static final String ACCESS_TOKEN_KEY = "access_token";
private static final String TOKEN_TYPE_KEY = "token_type";
Expand Down Expand Up @@ -59,4 +60,14 @@ public boolean recentlyCreated() {
return (createTimeMillis + CREATE_BUFFER) > System.currentTimeMillis();
}

@Override
public boolean isValid() {
return getToken() != null && getTokenType() != null;
}

@Override
public String getHttpAuthorization() {
return getTokenType() + " " + getToken();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ public static void checkResult(String[] command, ProcessResult result, boolean c
if (obj.has(ERROR_KEY) && obj.has(ERROR_DESCRIPTION_KEY)) {
String msg = String.format("The cwctl '%s' command failed with error: %s", CoreUtil.formatString(command, " "), obj.getString(ERROR_DESCRIPTION_KEY)); //$NON-NLS-1$
Logger.logError(msg);
throw new IOException(obj.getString(ERROR_DESCRIPTION_KEY));
throw new CLIException(obj.getString(ERROR_KEY), obj.getString(ERROR_DESCRIPTION_KEY));
}
}
} catch (JSONException e) {
Expand Down Expand Up @@ -248,4 +248,17 @@ public static void removeCWCTL(String version) throws IOException {
Logger.log("Removing folder: " + cwctlFolder.getAbsolutePath());
FileUtil.deleteDirectory(cwctlFolder.getAbsolutePath(), true);
}

@SuppressWarnings("serial")
public static class CLIException extends IOException {

public final String errorId;
public final String errorMsg;

public CLIException(String errorId, String errorMsg) {
super(errorMsg);
this.errorId = errorId;
this.errorMsg = errorMsg;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ public class TemplateUtil {
private static final String URL_OPTION = "--url";
private static final String NAME_OPTION = "--name";
private static final String DESCRIPTION_OPTION = "--description";
private static final String USERNAME_OPTION = "--username";
private static final String PASSWORD_OPTION = "--password";
private static final String PERSONAL_ACCESS_TOKEN_OPTION = "--personalAccessToken";

public static List<ProjectTemplateInfo> listTemplates(boolean enabledOnly, String conid, IProgressMonitor monitor) throws IOException, JSONException, TimeoutException {
SubMonitor mon = SubMonitor.convert(monitor, 100);
Expand Down Expand Up @@ -83,8 +86,26 @@ public static List<RepositoryInfo> listTemplateSources(String conid, IProgressMo
}
}

public static void addTemplateSource(String url, String name, String description, String conid, IProgressMonitor monitor) throws IOException, JSONException, TimeoutException {
runTemplateSourceCmd(REPO_ADD_CMD, new String[] {URL_OPTION, url, NAME_OPTION, name, DESCRIPTION_OPTION, description, CLIUtil.CON_ID_OPTION, conid}, null, monitor);
public static void addTemplateSource(String url, String username, String password, String accessToken, String name, String description, String conid, IProgressMonitor monitor) throws IOException, JSONException, TimeoutException {
List<String> options = new ArrayList<String>();
options.add(URL_OPTION);
options.add(url);
if (username != null && password != null) {
options.add(USERNAME_OPTION);
options.add(username);
options.add(PASSWORD_OPTION);
options.add(password);
} else if (accessToken != null) {
options.add(PERSONAL_ACCESS_TOKEN_OPTION);
options.add(accessToken);
}
options.add(NAME_OPTION);
options.add(name);
options.add(DESCRIPTION_OPTION);
options.add(description);
options.add(CLIUtil.CON_ID_OPTION);
options.add(conid);
runTemplateSourceCmd(REPO_ADD_CMD, options.toArray(new String[options.size()]), null, monitor);
}

public static void removeTemplateSource(String url, String conid, IProgressMonitor monitor) throws IOException, JSONException, TimeoutException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import org.json.JSONException;
import org.json.JSONObject;

public abstract class JSONObjectResult {
public class JSONObjectResult {

protected final JSONObject result;
protected final String type;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ public class RepositoryInfo extends JSONObjectResult {
public static final String ENABLED_KEY = "enabled";
public static final String PROTECTED_KEY = "protected";
public static final String STYLES_KEY = "projectStyles";
public static final String AUTHENTICATION_KEY = "authentication";
public static final String USERNAME_KEY = "username";

public RepositoryInfo(JSONObject repo) {
super(repo, "repository");
Expand Down Expand Up @@ -51,4 +53,17 @@ public boolean isProtected() {
public List<String> getStyles() {
return getStringArray(STYLES_KEY);
}

public boolean hasAuthentication() {
return hasKey(AUTHENTICATION_KEY);
}

public String getUsername() {
JSONObject obj = hasAuthentication() ? getObject(AUTHENTICATION_KEY) : null;
if (obj != null) {
JSONObjectResult authObj = new JSONObjectResult(obj, "template source auth");
return authObj.getString(USERNAME_KEY);
}
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.browser.IWebBrowser;
import org.eclipse.ui.browser.IWorkbenchBrowserSupport;
Expand Down Expand Up @@ -164,4 +165,8 @@ public static Optional<IConsole> getConsoleForLaunch(ILaunch launch) {
&& processes.contains(((org.eclipse.debug.ui.console.IConsole) console).getProcess()))
.findFirst();
}

public static String getTextValue(Text text) {
return text.getText() == null || text.getText().trim().isEmpty() ? null : text.getText().trim();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,7 @@ public class Messages extends NLS {
public static String RepoMgmtDescription;
public static String RepoMgmtLearnMoreLink;
public static String RepoMgmtAddButton;
public static String RepoMgmtEditButton;
public static String RepoMgmtRemoveButton;
public static String RepoMgmtDescriptionLabel;
public static String RepoMgmtStylesLabel;
Expand All @@ -510,17 +511,46 @@ public class Messages extends NLS {

public static String AddRepoDialogShell;
public static String AddRepoDialogTitle;
public static String AddRepoDialogMessage;
public static String EditRepoDialogShell;
public static String EditRepoDialogTitle;
public static String AddRepoURLPageMessage;
public static String AddRepoAuthPageMessage;
public static String AddRepoDetailsPageMessage;
public static String AddRepoDialogNameLabel;
public static String AddRepoDialogDescriptionLabel;
public static String AddRepoDialogUrlLabel;
public static String AddRepoDialogAutoFillButtonLabel;
public static String AddRepoDialogAutoFillButtonTooltip;
public static String AddRepoDialogInvalidUrlTitle;
public static String AddRepoDialogInvalidUrlError;
public static String AddRepoDialogInvalidUrlMsg;
public static String AddRepoDialogUrlPingTask;
public static String AddRepoDialogUrlPingFailedDefaultMsg;
public static String AddRepoDialogUrlPingFailedTitle;
public static String AddRepoDialogUrlPingFailedError;
public static String AddRepoDialogUrlPingFailedMsg;
public static String AddRepoDialogAuthRequiredCheckboxLabel;
public static String AddRepoDialogAuthRequiredCheckboxTooltip;
public static String AddRepoDialogLogonAuthButton;
public static String AddRepoDialogAccessTokenAuthButton;
public static String AddRepoDialogUsernameLabel;
public static String AddRepoDialogPasswordLabel;
public static String AddRepoDialogAccessTokenLabel;
public static String AddRepoDialogAuthTestButtonLabel;
public static String AddRepoDialogAuthTestTaskLabel;
public static String AddRepoDialogAuthTestFailedTitle;
public static String AddRepoDialogAuthTestFailedDefaultMsg;
public static String AddRepoDialogAuthTestFailedError;
public static String AddRepoDialogAuthTestSuccessMsg;
public static String AddRepoDialogAuthTestFailedMsg;
public static String AddRepoDialogResetButtonLabel;
public static String AddRepoDialogResetButtonTooltip;
public static String AddRepoDialogAutoFillTaskLabel;
public static String AddRepoDialogAutoFillNotAvailableMsg;
public static String AddRepoDialogNoName;
public static String AddRepoDialogNoDescription;
public static String AddRepoDialogNoUrl;
public static String AddRepoDialogNoUsername;
public static String AddRepoDialogNoPassword;
public static String AddRepoDialogNoAccessToken;

public static String RepoListTask;
public static String RepoUpdateTask;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,7 @@ RepoMgmtDialogMessage=Add, remove, enable and disable template sources
RepoMgmtDescription=Enable or disable template sources using the check boxes. Use the buttons to add and remove template sources. Default template sources cannot be removed.
RepoMgmtLearnMoreLink=Learn more...
RepoMgmtAddButton=&Add...
RepoMgmtEditButton=&Edit...
RepoMgmtRemoveButton=&Remove
RepoMgmtDescriptionLabel=Description:
RepoMgmtStylesLabel=Styles:
Expand All @@ -504,17 +505,46 @@ RepoMgmtAddFailed=An error occurred trying to add template source: {0}

AddRepoDialogShell=Add Template Source
AddRepoDialogTitle=Add a Template Source
AddRepoDialogMessage=Supply a URL, name, and description for the new template source
EditRepoDialogShell=Edit Template Source
EditRepoDialogTitle=Edit a Template Source
AddRepoURLPageMessage=Enter the URL of the template source and indicate if the URL requires authentication.
AddRepoAuthPageMessage=Provide authorization details for the template source.
AddRepoDetailsPageMessage=Provide the name and description for the template source.
AddRepoDialogNameLabel=&Name:
AddRepoDialogDescriptionLabel=&Description:
AddRepoDialogUrlLabel=&URL:
AddRepoDialogAutoFillButtonLabel=Auto &Fill from URL
AddRepoDialogAutoFillButtonTooltip=Fills in the name and description if available from the URL location
AddRepoDialogInvalidUrlTitle=Invalid URL
AddRepoDialogInvalidUrlError=The specified URL is not valid:\n\n{0}
AddRepoDialogInvalidUrlMsg=The specified URL is not valid.
AddRepoDialogUrlPingTask=Pinging: {0}
AddRepoDialogUrlPingFailedDefaultMsg=The ping failed with error code: {0}
AddRepoDialogUrlPingFailedTitle=Ping Error
AddRepoDialogUrlPingFailedError=The following error occurred while trying to ping URL: {0}\n\n{1}
AddRepoDialogUrlPingFailedMsg=Ping of the URL was unsuccessful.
AddRepoDialogAuthRequiredCheckboxLabel=&Authentication required for this URL
AddRepoDialogAuthRequiredCheckboxTooltip=Select if authentication is required for this URL.
AddRepoDialogLogonAuthButton=&Logon authentication
AddRepoDialogAccessTokenAuthButton=&Access token authentication
AddRepoDialogUsernameLabel=&Username:
AddRepoDialogPasswordLabel=&Password:
AddRepoDialogAccessTokenLabel=Access &token:
AddRepoDialogAuthTestButtonLabel=Te&st Authentication
AddRepoDialogAuthTestTaskLabel=Testing authentication for: {0}
AddRepoDialogAuthTestFailedTitle=Authentication Test
AddRepoDialogAuthTestFailedDefaultMsg=The authentication test failed with error code: {0}
AddRepoDialogAuthTestFailedError=The following error occurred while testing authentication for URL: {0}\n\n{1}
AddRepoDialogAuthTestSuccessMsg=The authentication test was successful.
AddRepoDialogAuthTestFailedMsg=The authentication test was not successful.
AddRepoDialogResetButtonLabel=&Restore Defaults
AddRepoDialogResetButtonTooltip=Reset to the defaults provided by the URL
AddRepoDialogAutoFillTaskLabel=Retrieving template source details
AddRepoDialogAutoFillNotAvailableMsg=The template source details could not be retrieved from the URL location
AddRepoDialogNoName=Fill in a name for the template source
AddRepoDialogNoDescription=Fill in a description for the template source
AddRepoDialogNoUrl=Fill in a URL for the template source
AddRepoDialogAutoFillNotAvailableMsg=The template source details could not be retrieved from the URL location.
AddRepoDialogNoName=Fill in a name for the template source.
AddRepoDialogNoDescription=Fill in a description for the template source.
AddRepoDialogNoUrl=Fill in a URL for the template source.
AddRepoDialogNoUsername=Fill in a username for template source authorization.
AddRepoDialogNoPassword=Fill in a password for template source authorization.
AddRepoDialogNoAccessToken=Fill in an access token for template source authorization.

RepoListTask=Retrieving template sources for: {0}
RepoUpdateTask=Updating template sources
Expand Down
Loading