summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteffen Pingel2012-01-14 15:30:22 (EST)
committerSteffen Pingel2012-01-14 15:30:22 (EST)
commit3c8980c5dee5179c54ed1d2c0c3d78d80fa2a492 (patch)
treeccecf69236c838c52921ec570c648ecddf0323cf
parente00266be4b874eeda2a8fd53a798fc106bc64373 (diff)
downloadorg.eclipse.mylyn.commons-3c8980c5dee5179c54ed1d2c0c3d78d80fa2a492.zip
org.eclipse.mylyn.commons-3c8980c5dee5179c54ed1d2c0c3d78d80fa2a492.tar.gz
org.eclipse.mylyn.commons-3c8980c5dee5179c54ed1d2c0c3d78d80fa2a492.tar.bz2
NEW - bug 367493: provide support for certificate authentication
https://bugs.eclipse.org/bugs/show_bug.cgi?id=367493 Change-Id: Ibc5d29ce41fee06c8afca23e750ea32c3d43c107
-rw-r--r--org.eclipse.mylyn.commons.core/src/org/eclipse/mylyn/commons/core/net/SslSupport.java5
-rw-r--r--org.eclipse.mylyn.commons.repositories.core/src/org/eclipse/mylyn/commons/repositories/core/RepositoryLocation.java5
-rw-r--r--org.eclipse.mylyn.commons.repositories.core/src/org/eclipse/mylyn/commons/repositories/core/auth/CertificateCredentials.java78
-rw-r--r--org.eclipse.mylyn.commons.repositories.core/src/org/eclipse/mylyn/commons/repositories/core/auth/UserCredentials.java8
-rw-r--r--org.eclipse.mylyn.commons.repositories.core/src/org/eclipse/mylyn/internal/commons/repositories/core/InMemoryCredentialsStore.java23
-rw-r--r--org.eclipse.mylyn.commons.repositories.http.core/META-INF/MANIFEST.MF2
-rw-r--r--org.eclipse.mylyn.commons.repositories.http.core/src/org/eclipse/mylyn/commons/repositories/http/core/CommonHttpClient.java42
-rw-r--r--org.eclipse.mylyn.commons.repositories.http.core/src/org/eclipse/mylyn/commons/repositories/http/core/CommonHttpOperation.java6
-rw-r--r--org.eclipse.mylyn.commons.repositories.http.core/src/org/eclipse/mylyn/commons/repositories/http/core/DefaultHttpOperation.java71
-rw-r--r--org.eclipse.mylyn.commons.repositories.http.core/src/org/eclipse/mylyn/commons/repositories/http/core/HttpRequestProcessor.java44
-rw-r--r--org.eclipse.mylyn.commons.repositories.http.core/src/org/eclipse/mylyn/commons/repositories/http/core/PollingSslProtocolSocketFactory.java42
-rw-r--r--org.eclipse.mylyn.commons.repositories.http.tests/META-INF/MANIFEST.MF1
-rw-r--r--org.eclipse.mylyn.commons.repositories.http.tests/src/org/eclipse/mylyn/commons/repositories/http/tests/CommonHttpClientTest.java102
-rw-r--r--org.eclipse.mylyn.commons.repositories.tests/src/org/eclipse/mylyn/commons/repositories/tests/core/AbstractCredentialsStoreTest.java11
-rw-r--r--org.eclipse.mylyn.commons.repositories.tests/src/org/eclipse/mylyn/commons/repositories/tests/core/CertificateCredentialsTest.java42
-rw-r--r--org.eclipse.mylyn.commons.repositories.tests/src/org/eclipse/mylyn/commons/repositories/tests/core/CredentialsFactoryTest.java2
-rw-r--r--org.eclipse.mylyn.commons.repositories.tests/src/org/eclipse/mylyn/commons/repositories/tests/core/InMemoryCredentialsStoreTest.java10
-rw-r--r--org.eclipse.mylyn.commons.repositories.ui/src/org/eclipse/mylyn/commons/repositories/ui/RepositoryLocationPart.java218
-rw-r--r--org.eclipse.mylyn.commons.repositories.ui/src/org/eclipse/mylyn/internal/commons/repositories/ui/auth/CertificateCredentialsProviderUi.java2
-rw-r--r--org.eclipse.mylyn.commons.sdk.util/.settings/.api_filters33
-rw-r--r--org.eclipse.mylyn.commons.sdk.util/META-INF/MANIFEST.MF1
-rw-r--r--org.eclipse.mylyn.commons.sdk.util/build.properties3
-rw-r--r--org.eclipse.mylyn.commons.sdk.util/src/org/eclipse/mylyn/commons/sdk/util/CommonTestUtil.java184
-rw-r--r--org.eclipse.mylyn.commons.sdk.util/src/org/eclipse/mylyn/commons/sdk/util/RepositoryTestFixture.java160
-rw-r--r--org.eclipse.mylyn.commons.sdk.util/testdata/keystorebin0 -> 2751 bytes
25 files changed, 978 insertions, 117 deletions
diff --git a/org.eclipse.mylyn.commons.core/src/org/eclipse/mylyn/commons/core/net/SslSupport.java b/org.eclipse.mylyn.commons.core/src/org/eclipse/mylyn/commons/core/net/SslSupport.java
index f70d848..ae5d92a 100644
--- a/org.eclipse.mylyn.commons.core/src/org/eclipse/mylyn/commons/core/net/SslSupport.java
+++ b/org.eclipse.mylyn.commons.core/src/org/eclipse/mylyn/commons/core/net/SslSupport.java
@@ -27,6 +27,8 @@ import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
+import org.eclipse.osgi.util.NLS;
+
/**
* Provides support for managing SSL connections.
*
@@ -118,7 +120,8 @@ public class SslSupport {
}
}
} catch (Exception cause) {
- IOException e = new SslCertificateException();
+ IOException e = new SslCertificateException(NLS.bind("Error accessing keystore: {0}",
+ cause.getMessage()));
e.initCause(cause);
throw e;
}
diff --git a/org.eclipse.mylyn.commons.repositories.core/src/org/eclipse/mylyn/commons/repositories/core/RepositoryLocation.java b/org.eclipse.mylyn.commons.repositories.core/src/org/eclipse/mylyn/commons/repositories/core/RepositoryLocation.java
index aa8f046..e001e27 100644
--- a/org.eclipse.mylyn.commons.repositories.core/src/org/eclipse/mylyn/commons/repositories/core/RepositoryLocation.java
+++ b/org.eclipse.mylyn.commons.repositories.core/src/org/eclipse/mylyn/commons/repositories/core/RepositoryLocation.java
@@ -94,6 +94,11 @@ public class RepositoryLocation extends PlatformObject {
this(createDefaultProperties(), LocationService.getDefault(), false);
}
+ public RepositoryLocation(String url) {
+ this();
+ setUrl(url);
+ }
+
public RepositoryLocation(Map<String, String> properties) {
this(properties, LocationService.getDefault(), true);
}
diff --git a/org.eclipse.mylyn.commons.repositories.core/src/org/eclipse/mylyn/commons/repositories/core/auth/CertificateCredentials.java b/org.eclipse.mylyn.commons.repositories.core/src/org/eclipse/mylyn/commons/repositories/core/auth/CertificateCredentials.java
index 27c7803..aaa87f1 100644
--- a/org.eclipse.mylyn.commons.repositories.core/src/org/eclipse/mylyn/commons/repositories/core/auth/CertificateCredentials.java
+++ b/org.eclipse.mylyn.commons.repositories.core/src/org/eclipse/mylyn/commons/repositories/core/auth/CertificateCredentials.java
@@ -12,7 +12,6 @@
package org.eclipse.mylyn.commons.repositories.core.auth;
import org.eclipse.core.runtime.Assert;
-import org.eclipse.equinox.security.storage.StorageException;
/**
* @author Steffen Pingel
@@ -21,17 +20,44 @@ public class CertificateCredentials extends AuthenticationCredentials {
private final String keyStoreFileName;
+ private final String keyStoreType;
+
private final String password;
- public CertificateCredentials(String keyStoreFileName, String password) {
+ private final boolean savePassword;
+
+ private final boolean hasSecrets;
+
+ public CertificateCredentials(String keyStoreFileName, String password, String keyStoreType) {
+ this(keyStoreFileName, password, keyStoreType, true, true);
+ }
+
+ public CertificateCredentials(String keyStoreFileName, String password, String keyStoreType, boolean savePassword) {
+ this(keyStoreFileName, password, keyStoreType, savePassword, true);
+ }
+
+ CertificateCredentials(String keyStoreFileName, String password, String keyStoreType, boolean savePassword,
+ boolean hasSecrets) {
Assert.isNotNull(password);
this.keyStoreFileName = keyStoreFileName;
this.password = password;
+ this.keyStoreType = keyStoreType;
+ this.savePassword = savePassword;
+ this.hasSecrets = hasSecrets;
+ }
+
+ protected CertificateCredentials(ICredentialsStore store, String prefix, boolean loadSecrets) {
+ this(
+ store.get(prefix + ".keyStoreFileName", null), (loadSecrets) ? store.get(prefix + ".password", "") : "", //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$
+ store.get(prefix + ".keyStoreType", null), store.getBoolean(prefix + ".savePassword", false), loadSecrets); //$NON-NLS-1$ //$NON-NLS-2$
}
- protected CertificateCredentials(ICredentialsStore store, String prefix, boolean loadSecrets)
- throws StorageException {
- this(store.get(prefix + ".keyStoreFileName", null), (loadSecrets) ? store.get(prefix + ".password", "") : ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ @Override
+ public void clear(ICredentialsStore store, String prefix) {
+ store.remove(prefix + ".keyStoreFileName"); //$NON-NLS-1$
+ store.remove(prefix + ".password"); //$NON-NLS-1$
+ store.remove(prefix + ".keyStoreType"); //$NON-NLS-1$
+ store.remove(prefix + ".savePassword"); //$NON-NLS-1$
}
@Override
@@ -46,6 +72,9 @@ public class CertificateCredentials extends AuthenticationCredentials {
return false;
}
CertificateCredentials other = (CertificateCredentials) obj;
+ if (hasSecrets != other.hasSecrets) {
+ return false;
+ }
if (keyStoreFileName == null) {
if (other.keyStoreFileName != null) {
return false;
@@ -53,6 +82,13 @@ public class CertificateCredentials extends AuthenticationCredentials {
} else if (!keyStoreFileName.equals(other.keyStoreFileName)) {
return false;
}
+ if (keyStoreType == null) {
+ if (other.keyStoreType != null) {
+ return false;
+ }
+ } else if (!keyStoreType.equals(other.keyStoreType)) {
+ return false;
+ }
if (password == null) {
if (other.password != null) {
return false;
@@ -60,6 +96,9 @@ public class CertificateCredentials extends AuthenticationCredentials {
} else if (!password.equals(other.password)) {
return false;
}
+ if (savePassword != other.savePassword) {
+ return false;
+ }
return true;
}
@@ -67,29 +106,38 @@ public class CertificateCredentials extends AuthenticationCredentials {
return keyStoreFileName;
}
+ public String getKeyStoreType() {
+ return keyStoreType;
+ }
+
public String getPassword() {
return password;
}
+ public boolean getSavePassword() {
+ return savePassword;
+ }
+
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
+ result = prime * result + (hasSecrets ? 1231 : 1237);
result = prime * result + ((keyStoreFileName == null) ? 0 : keyStoreFileName.hashCode());
+ result = prime * result + ((keyStoreType == null) ? 0 : keyStoreType.hashCode());
result = prime * result + ((password == null) ? 0 : password.hashCode());
+ result = prime * result + (savePassword ? 1231 : 1237);
return result;
}
@Override
- public void clear(ICredentialsStore store, String prefix) {
- store.remove(prefix + ".keyStoreFileName"); //$NON-NLS-1$
- store.remove(prefix + ".password"); //$NON-NLS-1$
- }
-
- @Override
public void save(ICredentialsStore store, String prefix) {
store.put(prefix + ".keyStoreFileName", keyStoreFileName, false); //$NON-NLS-1$
- store.put(prefix + ".password", password, true); //$NON-NLS-1$
+ if (hasSecrets) {
+ store.put(prefix + ".password", password, true); //$NON-NLS-1$
+ }
+ store.put(prefix + ".keyStoreType", keyStoreType, false); //$NON-NLS-1$
+ store.putBoolean(prefix + ".savePassword", savePassword, false); //$NON-NLS-1$
}
@Override
@@ -99,6 +147,12 @@ public class CertificateCredentials extends AuthenticationCredentials {
builder.append(keyStoreFileName);
builder.append(", password="); //$NON-NLS-1$
builder.append((password == null) ? password : "********"); //$NON-NLS-1$
+ builder.append(", keyStoreType="); //$NON-NLS-1$
+ builder.append(keyStoreType);
+ builder.append(", savePassword="); //$NON-NLS-1$
+ builder.append(savePassword);
+ builder.append(", hasSecrets="); //$NON-NLS-1$
+ builder.append(hasSecrets);
builder.append("]"); //$NON-NLS-1$
return builder.toString();
}
diff --git a/org.eclipse.mylyn.commons.repositories.core/src/org/eclipse/mylyn/commons/repositories/core/auth/UserCredentials.java b/org.eclipse.mylyn.commons.repositories.core/src/org/eclipse/mylyn/commons/repositories/core/auth/UserCredentials.java
index 2810eeb..617df49 100644
--- a/org.eclipse.mylyn.commons.repositories.core/src/org/eclipse/mylyn/commons/repositories/core/auth/UserCredentials.java
+++ b/org.eclipse.mylyn.commons.repositories.core/src/org/eclipse/mylyn/commons/repositories/core/auth/UserCredentials.java
@@ -90,6 +90,9 @@ public class UserCredentials extends AuthenticationCredentials {
} else if (!domain.equals(other.domain)) {
return false;
}
+ if (hasSecrets != other.hasSecrets) {
+ return false;
+ }
if (password == null) {
if (other.password != null) {
return false;
@@ -97,6 +100,9 @@ public class UserCredentials extends AuthenticationCredentials {
} else if (!password.equals(other.password)) {
return false;
}
+ if (savePassword != other.savePassword) {
+ return false;
+ }
if (userName == null) {
if (other.userName != null) {
return false;
@@ -128,7 +134,9 @@ public class UserCredentials extends AuthenticationCredentials {
final int prime = 31;
int result = 1;
result = prime * result + ((domain == null) ? 0 : domain.hashCode());
+ result = prime * result + (hasSecrets ? 1231 : 1237);
result = prime * result + ((password == null) ? 0 : password.hashCode());
+ result = prime * result + (savePassword ? 1231 : 1237);
result = prime * result + ((userName == null) ? 0 : userName.hashCode());
return result;
}
diff --git a/org.eclipse.mylyn.commons.repositories.core/src/org/eclipse/mylyn/internal/commons/repositories/core/InMemoryCredentialsStore.java b/org.eclipse.mylyn.commons.repositories.core/src/org/eclipse/mylyn/internal/commons/repositories/core/InMemoryCredentialsStore.java
index 6a23b77..5c6cfce 100644
--- a/org.eclipse.mylyn.commons.repositories.core/src/org/eclipse/mylyn/internal/commons/repositories/core/InMemoryCredentialsStore.java
+++ b/org.eclipse.mylyn.commons.repositories.core/src/org/eclipse/mylyn/internal/commons/repositories/core/InMemoryCredentialsStore.java
@@ -35,6 +35,8 @@ public class InMemoryCredentialsStore implements ICredentialsStore {
Object value;
+ Class<?> type;
+
}
static Map<String, InMemoryCredentialsStore> storeById = new HashMap<String, InMemoryCredentialsStore>();
@@ -94,11 +96,11 @@ public class InMemoryCredentialsStore implements ICredentialsStore {
for (Map.Entry<String, Item> entry : store.entrySet()) {
Item item = entry.getValue();
if (item != null) {
- if (item.value instanceof String) {
+ if (item.type == String.class) {
target.put(entry.getKey(), (String) item.value, item.encrypted, item.persisted);
- } else if (item.value instanceof byte[]) {
+ } else if (item.type == byte[].class) {
target.putByteArray(entry.getKey(), (byte[]) item.value, item.encrypted);
- } else if (item.value instanceof Boolean) {
+ } else if (item.type == boolean.class) {
target.putBoolean(entry.getKey(), (Boolean) item.value, item.encrypted);
}
} else {
@@ -125,7 +127,7 @@ public class InMemoryCredentialsStore implements ICredentialsStore {
if (item == null && parent != null) {
return parent.get(key, def);
}
- return (item != null && item.value instanceof String) ? (String) item.value : def;
+ return (item != null && item.type == String.class) ? (String) item.value : def;
}
public synchronized boolean getBoolean(String key, boolean def) {
@@ -133,7 +135,7 @@ public class InMemoryCredentialsStore implements ICredentialsStore {
if (item == null && parent != null) {
return parent.getBoolean(key, def);
}
- return (item != null && item.value instanceof Boolean) ? (Boolean) item.value : def;
+ return (item != null && item.type == boolean.class) ? (Boolean) item.value : def;
}
public synchronized byte[] getByteArray(String key, byte[] def) {
@@ -141,7 +143,7 @@ public class InMemoryCredentialsStore implements ICredentialsStore {
if (item == null && parent != null) {
return parent.getByteArray(key, def);
}
- return (item != null && item.value instanceof byte[]) ? (byte[]) item.value : def;
+ return (item != null && item.type == byte[].class) ? (byte[]) item.value : def;
}
public String getId() {
@@ -168,15 +170,15 @@ public class InMemoryCredentialsStore implements ICredentialsStore {
}
public synchronized void put(String key, String value, boolean encrypt, boolean persist) {
- store.put(key, createItem(value, encrypt, persist));
+ store.put(key, createItem(String.class, value, encrypt, persist));
}
public synchronized void putBoolean(String key, boolean value, boolean encrypt) {
- store.put(key, createItem(value, encrypt, true));
+ store.put(key, createItem(boolean.class, value, encrypt, true));
}
public synchronized void putByteArray(String key, byte[] value, boolean encrypt) {
- store.put(key, createItem(value, encrypt, encrypt));
+ store.put(key, createItem(byte[].class, value, encrypt, encrypt));
}
public synchronized void remove(String key) {
@@ -187,11 +189,12 @@ public class InMemoryCredentialsStore implements ICredentialsStore {
}
}
- private Item createItem(Object value, boolean encrypt, boolean persist) {
+ private Item createItem(Class<?> type, Object value, boolean encrypt, boolean persist) {
Item item = new Item();
item.value = value;
item.encrypted = encrypt;
item.persisted = persist;
+ item.type = type;
return item;
}
diff --git a/org.eclipse.mylyn.commons.repositories.http.core/META-INF/MANIFEST.MF b/org.eclipse.mylyn.commons.repositories.http.core/META-INF/MANIFEST.MF
index f958ffc..111a796 100644
--- a/org.eclipse.mylyn.commons.repositories.http.core/META-INF/MANIFEST.MF
+++ b/org.eclipse.mylyn.commons.repositories.http.core/META-INF/MANIFEST.MF
@@ -22,10 +22,12 @@ Import-Package: org.apache.commons.logging;version="[1.0.4,2.0.0)",
org.apache.http.client;version="4.1.0",
org.apache.http.client.methods;version="4.1.0",
org.apache.http.client.params;version="4.1.0",
+ org.apache.http.client.protocol;version="4.1.0",
org.apache.http.conn;version="4.1.0",
org.apache.http.conn.params;version="4.1.0",
org.apache.http.conn.scheme;version="4.1.0",
org.apache.http.impl.client;version="4.1.0",
org.apache.http.impl.conn.tsccm;version="4.1.0",
+ org.apache.http.message;version="4.1.0",
org.apache.http.params;version="4.1.0",
org.apache.http.protocol;version="4.1.0"
diff --git a/org.eclipse.mylyn.commons.repositories.http.core/src/org/eclipse/mylyn/commons/repositories/http/core/CommonHttpClient.java b/org.eclipse.mylyn.commons.repositories.http.core/src/org/eclipse/mylyn/commons/repositories/http/core/CommonHttpClient.java
index 39fc2ac..38a85d7 100644
--- a/org.eclipse.mylyn.commons.repositories.http.core/src/org/eclipse/mylyn/commons/repositories/http/core/CommonHttpClient.java
+++ b/org.eclipse.mylyn.commons.repositories.http.core/src/org/eclipse/mylyn/commons/repositories/http/core/CommonHttpClient.java
@@ -13,21 +13,28 @@ package org.eclipse.mylyn.commons.repositories.http.core;
import java.io.IOException;
+import javax.net.ssl.TrustManager;
+
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
+import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpRequestBase;
+import org.apache.http.client.protocol.ClientContext;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.impl.client.AbstractHttpClient;
-import org.apache.http.impl.client.ContentEncodingHttpClient;
+import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.HttpContext;
import org.apache.http.protocol.SyncBasicHttpContext;
import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.mylyn.commons.core.net.SslSupport;
+import org.eclipse.mylyn.commons.core.net.TrustAllTrustManager;
import org.eclipse.mylyn.commons.core.operations.IOperationMonitor;
import org.eclipse.mylyn.commons.repositories.core.RepositoryLocation;
import org.eclipse.mylyn.commons.repositories.core.auth.AuthenticationCredentials;
import org.eclipse.mylyn.commons.repositories.core.auth.AuthenticationException;
import org.eclipse.mylyn.commons.repositories.core.auth.AuthenticationRequest;
import org.eclipse.mylyn.commons.repositories.core.auth.AuthenticationType;
+import org.eclipse.mylyn.commons.repositories.core.auth.CertificateCredentials;
import org.eclipse.mylyn.commons.repositories.core.auth.UserCredentials;
/**
@@ -53,8 +60,15 @@ public class CommonHttpClient {
this.httpAuthenticationType = AuthenticationType.HTTP;
}
+ public <T> T executeGet(String requestPath, IOperationMonitor monitor, HttpRequestProcessor<T> processor)
+ throws IOException {
+ HttpGet request = new HttpGet(location.getUrl() + requestPath);
+ DefaultHttpOperation<T> op = new DefaultHttpOperation<T>(this, request, processor);
+ return op.run(monitor);
+ }
+
public HttpResponse execute(HttpRequestBase request, IOperationMonitor monitor) throws IOException {
- prepareRequest(monitor);
+ prepareRequest(request, monitor);
return HttpUtil.execute(getHttpClient(), HttpUtil.createHost(request), context, request, monitor);
}
@@ -93,19 +107,32 @@ public class CommonHttpClient {
this.httpAuthenticationType = httpAuthenticationType;
}
- private void prepareRequest(IOperationMonitor monitor) {
- UserCredentials credentials = location.getCredentials(httpAuthenticationType);
- if (credentials != null) {
- HttpUtil.configureAuthentication(getHttpClient(), location, credentials);
+ private void prepareRequest(HttpRequestBase request, IOperationMonitor monitor) {
+ UserCredentials httpCredentials = location.getCredentials(httpAuthenticationType);
+ if (httpCredentials != null) {
+ HttpUtil.configureAuthentication(getHttpClient(), location, httpCredentials);
}
HttpUtil.configureProxy(getHttpClient(), location);
+ HttpUtil.configureProxy(getHttpClient(), location);
+
+ CertificateCredentials socketCredentials = location.getCredentials(AuthenticationType.CERTIFICATE);
+ if (socketCredentials != null) {
+ SslSupport support = new SslSupport(new TrustManager[] { new TrustAllTrustManager() },
+ socketCredentials.getKeyStoreFileName(), socketCredentials.getPassword(),
+ socketCredentials.getKeyStoreType());
+ request.getParams().setParameter(SslSupport.class.getName(), support);
+ } else {
+ // remove the token that associates certificate credentials with the connection
+ context.removeAttribute(ClientContext.USER_TOKEN);
+ }
}
protected void authenticate(IOperationMonitor monitor) throws IOException {
}
protected AbstractHttpClient createHttpClient(String userAgent) {
- AbstractHttpClient client = new ContentEncodingHttpClient() {
+ // disabled due to https://issues.apache.org/jira/browse/HTTPCORE-257: new ContentEncodingHttpClient() {
+ AbstractHttpClient client = new DefaultHttpClient() {
@Override
protected ClientConnectionManager createClientConnectionManager() {
return CommonHttpClient.this.createHttpClientConnectionManager();
@@ -123,7 +150,6 @@ public class CommonHttpClient {
}
protected ClientConnectionManager createHttpClientConnectionManager() {
- // FIXME handle certificate authentication
return HttpUtil.getConnectionManager();
}
diff --git a/org.eclipse.mylyn.commons.repositories.http.core/src/org/eclipse/mylyn/commons/repositories/http/core/CommonHttpOperation.java b/org.eclipse.mylyn.commons.repositories.http.core/src/org/eclipse/mylyn/commons/repositories/http/core/CommonHttpOperation.java
index 89fe3d8..915a927 100644
--- a/org.eclipse.mylyn.commons.repositories.http.core/src/org/eclipse/mylyn/commons/repositories/http/core/CommonHttpOperation.java
+++ b/org.eclipse.mylyn.commons.repositories.http.core/src/org/eclipse/mylyn/commons/repositories/http/core/CommonHttpOperation.java
@@ -36,6 +36,10 @@ public abstract class CommonHttpOperation<T> {
this.client = client;
}
+ public CommonHttpOperation(CommonHttpClient client, HttpRequestBase request) {
+ this.client = client;
+ }
+
protected void authenticate(IOperationMonitor monitor) throws IOException {
client.authenticate(monitor);
}
@@ -52,7 +56,7 @@ public abstract class CommonHttpOperation<T> {
return new HttpPost(requestPath);
}
- protected CommonHttpResponse execute(HttpRequestBase request, IOperationMonitor monitor) throws IOException {
+ public CommonHttpResponse execute(HttpRequestBase request, IOperationMonitor monitor) throws IOException {
monitor = OperationUtil.convert(monitor);
try {
diff --git a/org.eclipse.mylyn.commons.repositories.http.core/src/org/eclipse/mylyn/commons/repositories/http/core/DefaultHttpOperation.java b/org.eclipse.mylyn.commons.repositories.http.core/src/org/eclipse/mylyn/commons/repositories/http/core/DefaultHttpOperation.java
new file mode 100644
index 0000000..81fdd85
--- /dev/null
+++ b/org.eclipse.mylyn.commons.repositories.http.core/src/org/eclipse/mylyn/commons/repositories/http/core/DefaultHttpOperation.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Tasktop Technologies 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:
+ * Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.commons.repositories.http.core;
+
+import java.io.IOException;
+
+import org.apache.http.client.methods.HttpRequestBase;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.mylyn.commons.core.operations.IOperationMonitor;
+
+/**
+ * @author Steffen Pingel
+ */
+class DefaultHttpOperation<T> extends CommonHttpOperation<T> {
+
+ private final HttpRequestProcessor<T> processor;
+
+ private final HttpRequestBase request;
+
+ public DefaultHttpOperation(CommonHttpClient client, HttpRequestBase request, HttpRequestProcessor<T> processor) {
+ super(client);
+ Assert.isNotNull(processor);
+ this.request = request;
+ this.processor = processor;
+ }
+
+ public T run(IOperationMonitor monitor) throws IOException {
+ CommonHttpResponse response = execute(request, monitor);
+ return (processor.autoRelease()) ? processAndRelease(response, monitor) : process(response, monitor);
+ }
+
+ protected T doProcess(CommonHttpResponse response, IOperationMonitor monitor) throws IOException {
+ return processor.doProcess(response, monitor);
+ }
+
+ protected void doValidate(CommonHttpResponse response, IOperationMonitor monitor) throws IOException {
+ processor.doValidate(response, monitor);
+ }
+
+ protected T process(CommonHttpResponse response, IOperationMonitor monitor) throws IOException {
+ try {
+ doValidate(response, monitor);
+ return doProcess(response, monitor);
+ } catch (IOException e) {
+ response.release(monitor);
+ throw e;
+ } catch (RuntimeException e) {
+ response.release(monitor);
+ throw e;
+ }
+ }
+
+ protected T processAndRelease(CommonHttpResponse response, IOperationMonitor monitor) throws IOException {
+ try {
+ doValidate(response, monitor);
+ return doProcess(response, monitor);
+ } finally {
+ response.release(monitor);
+ }
+ }
+
+}
diff --git a/org.eclipse.mylyn.commons.repositories.http.core/src/org/eclipse/mylyn/commons/repositories/http/core/HttpRequestProcessor.java b/org.eclipse.mylyn.commons.repositories.http.core/src/org/eclipse/mylyn/commons/repositories/http/core/HttpRequestProcessor.java
new file mode 100644
index 0000000..ec27d8b
--- /dev/null
+++ b/org.eclipse.mylyn.commons.repositories.http.core/src/org/eclipse/mylyn/commons/repositories/http/core/HttpRequestProcessor.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Tasktop Technologies 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:
+ * Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.commons.repositories.http.core;
+
+import java.io.IOException;
+
+import org.eclipse.mylyn.commons.core.operations.IOperationMonitor;
+
+/**
+ * @author Steffen Pingel
+ */
+public abstract class HttpRequestProcessor<T> {
+
+ private final boolean autoRelease;
+
+ public HttpRequestProcessor() {
+ this(true);
+ }
+
+ public HttpRequestProcessor(boolean autoRelease) {
+ this.autoRelease = autoRelease;
+ }
+
+ public boolean autoRelease() {
+ return autoRelease;
+ }
+
+ protected T doProcess(CommonHttpResponse response, IOperationMonitor monitor) throws IOException {
+ return null;
+ }
+
+ protected void doValidate(CommonHttpResponse response, IOperationMonitor monitor) throws IOException {
+ }
+
+}
diff --git a/org.eclipse.mylyn.commons.repositories.http.core/src/org/eclipse/mylyn/commons/repositories/http/core/PollingSslProtocolSocketFactory.java b/org.eclipse.mylyn.commons.repositories.http.core/src/org/eclipse/mylyn/commons/repositories/http/core/PollingSslProtocolSocketFactory.java
index aa3aa6d..b83a091 100644
--- a/org.eclipse.mylyn.commons.repositories.http.core/src/org/eclipse/mylyn/commons/repositories/http/core/PollingSslProtocolSocketFactory.java
+++ b/org.eclipse.mylyn.commons.repositories.http.core/src/org/eclipse/mylyn/commons/repositories/http/core/PollingSslProtocolSocketFactory.java
@@ -37,34 +37,45 @@ import org.eclipse.mylyn.commons.core.operations.MonitoredOperation;
*/
class PollingSslProtocolSocketFactory implements LayeredSchemeSocketFactory {
- private final SslSupport sslSupport;
+ private final SslSupport defaultSslSupport;
public PollingSslProtocolSocketFactory() {
this(new SslSupport(new TrustManager[] { new TrustAllTrustManager() }));
}
public PollingSslProtocolSocketFactory(SslSupport sslSupport) {
- this.sslSupport = sslSupport;
+ this.defaultSslSupport = sslSupport;
}
public Socket connectSocket(Socket sock, InetSocketAddress remoteAddress, InetSocketAddress localAddress,
HttpParams params) throws IOException, UnknownHostException, ConnectTimeoutException {
Assert.isNotNull(params);
+ final Socket socket = (sock != null) ? sock : createSocket(params);
+
+ if (localAddress != null) {
+ socket.setReuseAddress(HttpConnectionParams.getSoReuseaddr(params));
+ socket.bind(localAddress);
+ }
- final Socket socket = NetUtil.configureSocket(getSocketFactory().createSocket());
int connTimeout = HttpConnectionParams.getConnectionTimeout(params);
- socket.bind(localAddress);
NetUtil.connect(socket, remoteAddress, connTimeout, MonitoredOperation.getCurrentOperation());
- return socket;
+
+ if (socket instanceof SSLSocket) {
+ return socket;
+ } else {
+ return getSslSupport(params).getSocketFactory().createSocket(socket, remoteAddress.getHostName(),
+ remoteAddress.getPort(), true);
+ }
}
public Socket createLayeredSocket(Socket socket, String target, int port, boolean autoClose) throws IOException,
UnknownHostException {
- return NetUtil.configureSocket(getSocketFactory().createSocket(socket, target, port, autoClose));
+ return NetUtil.configureSocket(getDefaultSocketFactory().createSocket(socket, target, port, autoClose));
}
public Socket createSocket(HttpParams params) throws IOException {
- return NetUtil.configureSocket(getSocketFactory().createSocket());
+ Assert.isNotNull(params);
+ return NetUtil.configureSocket(getSslSupport(params).getSocketFactory().createSocket());
}
@Override
@@ -79,25 +90,25 @@ class PollingSslProtocolSocketFactory implements LayeredSchemeSocketFactory {
return false;
}
PollingSslProtocolSocketFactory other = (PollingSslProtocolSocketFactory) obj;
- if (sslSupport == null) {
- if (other.sslSupport != null) {
+ if (defaultSslSupport == null) {
+ if (other.defaultSslSupport != null) {
return false;
}
- } else if (!sslSupport.equals(other.sslSupport)) {
+ } else if (!defaultSslSupport.equals(other.defaultSslSupport)) {
return false;
}
return true;
}
- public SSLSocketFactory getSocketFactory() throws IOException {
- return sslSupport.getSocketFactory();
+ public SSLSocketFactory getDefaultSocketFactory() throws IOException {
+ return defaultSslSupport.getSocketFactory();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
- result = prime * result + ((sslSupport == null) ? 0 : sslSupport.hashCode());
+ result = prime * result + ((defaultSslSupport == null) ? 0 : defaultSslSupport.hashCode());
return result;
}
@@ -112,4 +123,9 @@ class PollingSslProtocolSocketFactory implements LayeredSchemeSocketFactory {
return true;
}
+ private SslSupport getSslSupport(HttpParams params) {
+ SslSupport sslSupport = (SslSupport) params.getParameter(SslSupport.class.getName());
+ return (sslSupport != null) ? sslSupport : defaultSslSupport;
+ }
+
}
diff --git a/org.eclipse.mylyn.commons.repositories.http.tests/META-INF/MANIFEST.MF b/org.eclipse.mylyn.commons.repositories.http.tests/META-INF/MANIFEST.MF
index 378b698..dac284a 100644
--- a/org.eclipse.mylyn.commons.repositories.http.tests/META-INF/MANIFEST.MF
+++ b/org.eclipse.mylyn.commons.repositories.http.tests/META-INF/MANIFEST.MF
@@ -26,6 +26,7 @@ Import-Package: org.apache.commons.logging;version="[1.0.4,2.0.0)",
org.apache.http.impl.client;version="4.1.0",
org.apache.http.impl.conn;version="4.1.0",
org.apache.http.impl.conn.tsccm;version="4.1.0",
+ org.apache.http.message;version="4.1.0",
org.apache.http.params;version="4.1.0",
org.apache.http.protocol;version="4.1.0",
org.apache.http.util;version="4.1.0"
diff --git a/org.eclipse.mylyn.commons.repositories.http.tests/src/org/eclipse/mylyn/commons/repositories/http/tests/CommonHttpClientTest.java b/org.eclipse.mylyn.commons.repositories.http.tests/src/org/eclipse/mylyn/commons/repositories/http/tests/CommonHttpClientTest.java
index 0c34fb8..82aaa62 100644
--- a/org.eclipse.mylyn.commons.repositories.http.tests/src/org/eclipse/mylyn/commons/repositories/http/tests/CommonHttpClientTest.java
+++ b/org.eclipse.mylyn.commons.repositories.http.tests/src/org/eclipse/mylyn/commons/repositories/http/tests/CommonHttpClientTest.java
@@ -13,16 +13,25 @@ package org.eclipse.mylyn.commons.repositories.http.tests;
import static org.junit.Assert.assertEquals;
+import java.io.IOException;
+
+import javax.net.ssl.SSLHandshakeException;
+
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.Credentials;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.methods.HttpGet;
+import org.eclipse.mylyn.commons.core.operations.IOperationMonitor;
import org.eclipse.mylyn.commons.repositories.core.RepositoryLocation;
import org.eclipse.mylyn.commons.repositories.core.auth.AuthenticationType;
import org.eclipse.mylyn.commons.repositories.core.auth.UserCredentials;
import org.eclipse.mylyn.commons.repositories.http.core.CommonHttpClient;
+import org.eclipse.mylyn.commons.repositories.http.core.CommonHttpResponse;
+import org.eclipse.mylyn.commons.repositories.http.core.HttpRequestProcessor;
+import org.eclipse.mylyn.commons.repositories.http.core.HttpUtil;
+import org.eclipse.mylyn.commons.sdk.util.CommonTestUtil;
import org.junit.Test;
/**
@@ -31,51 +40,112 @@ import org.junit.Test;
public class CommonHttpClientTest {
@Test
+ public void testExecuteGet() throws IOException {
+ RepositoryLocation location = new RepositoryLocation("http://mylyn.org");
+ CommonHttpClient client = new CommonHttpClient(location);
+ Integer result = client.executeGet("/", null, new HttpRequestProcessor<Integer>() {
+ @Override
+ protected Integer doProcess(CommonHttpResponse response, IOperationMonitor monitor) throws IOException {
+ return response.getStatusCode();
+ }
+ });
+ assertEquals(HttpStatus.SC_OK, result.intValue());
+ }
+
+ @Test
public void testGetRequest() throws Exception {
RepositoryLocation location = new RepositoryLocation();
- location.setUrl("http://eclipse.org/");
+ location.setUrl("http://mylyn.org/");
HttpGet request = new HttpGet(location.getUrl());
CommonHttpClient client = new CommonHttpClient(location);
HttpResponse response = client.execute(request, null);
- assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
+ try {
+ assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
+ } finally {
+ HttpUtil.release(request, response, null);
+ }
}
@Test
public void testHttpAuthenticationTypeHttp() throws Exception {
RepositoryLocation location = new RepositoryLocation();
- location.setUrl("http://eclipse.org/");
+ location.setUrl("http://mylyn.org/");
location.setCredentials(AuthenticationType.HTTP, new UserCredentials("username", "password"));
HttpGet request = new HttpGet(location.getUrl());
CommonHttpClient client = new CommonHttpClient(location);
- client.execute(request, null);
-
- AuthScope authScope = new AuthScope("eclipse.org", 80, AuthScope.ANY_REALM);
- Credentials httpCredentials = client.getHttpClient().getCredentialsProvider().getCredentials(authScope);
- assertEquals(new UsernamePasswordCredentials("username", "password"), httpCredentials);
+ HttpResponse response = client.execute(request, null);
+ try {
+ AuthScope authScope = new AuthScope("mylyn.org", 80, AuthScope.ANY_REALM);
+ Credentials httpCredentials = client.getHttpClient().getCredentialsProvider().getCredentials(authScope);
+ assertEquals(new UsernamePasswordCredentials("username", "password"), httpCredentials);
+ } finally {
+ HttpUtil.release(request, response, null);
+ }
}
@Test
public void testHttpAuthenticationTypeRepository() throws Exception {
RepositoryLocation location = new RepositoryLocation();
- location.setUrl("http://eclipse.org/");
+ location.setUrl("http://mylyn.org/");
location.setCredentials(AuthenticationType.REPOSITORY, new UserCredentials("username", "password"));
HttpGet request = new HttpGet(location.getUrl());
CommonHttpClient client = new CommonHttpClient(location);
- AuthScope authScope = new AuthScope("eclipse.org", 80, AuthScope.ANY_REALM);
+ AuthScope authScope = new AuthScope("mylyn.org", 80, AuthScope.ANY_REALM);
// credentials should be ignored
- client.execute(request, null);
- Credentials httpCredentials = client.getHttpClient().getCredentialsProvider().getCredentials(authScope);
- assertEquals(null, httpCredentials);
+ HttpResponse response = client.execute(request, null);
+ try {
+ Credentials httpCredentials = client.getHttpClient().getCredentialsProvider().getCredentials(authScope);
+ assertEquals(null, httpCredentials);
+ } finally {
+ HttpUtil.release(request, response, null);
+ }
client.setHttpAuthenticationType(AuthenticationType.REPOSITORY);
// credentials should now be used
- client.execute(request, null);
- httpCredentials = client.getHttpClient().getCredentialsProvider().getCredentials(authScope);
- assertEquals(new UsernamePasswordCredentials("username", "password"), httpCredentials);
+ response = client.execute(request, null);
+ try {
+ Credentials httpCredentials = client.getHttpClient().getCredentialsProvider().getCredentials(authScope);
+ assertEquals(new UsernamePasswordCredentials("username", "password"), httpCredentials);
+ } finally {
+ HttpUtil.release(request, response, null);
+ }
+ }
+
+ @Test(expected = SSLHandshakeException.class)
+ public void testCertificateAuthenticationNoCertificate() throws Exception {
+ RepositoryLocation location = new RepositoryLocation();
+ location.setUrl("https://mylyn.org/secure/index.txt");
+
+ HttpGet request = new HttpGet(location.getUrl());
+ CommonHttpClient client = new CommonHttpClient(location);
+ HttpResponse response = client.execute(request, null);
+ HttpUtil.release(request, response, null);
+ }
+
+ @Test(expected = SSLHandshakeException.class)
+ public void testCertificateAuthenticationCertificate() throws Exception {
+ RepositoryLocation location = new RepositoryLocation();
+ location.setUrl("https://mylyn.org/secure/index.txt");
+ location.setCredentials(AuthenticationType.CERTIFICATE, CommonTestUtil.getCertificateCredentials());
+
+ HttpGet request = new HttpGet(location.getUrl());
+ CommonHttpClient client = new CommonHttpClient(location);
+ HttpResponse response = client.execute(request, null);
+ try {
+ assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
+ } finally {
+ HttpUtil.release(request, response, null);
+ }
+
+ location.setCredentials(AuthenticationType.CERTIFICATE, null);
+ // the request should now fail
+ request = new HttpGet(location.getUrl());
+ response = client.execute(request, null);
+ HttpUtil.release(request, response, null);
}
}
diff --git a/org.eclipse.mylyn.commons.repositories.tests/src/org/eclipse/mylyn/commons/repositories/tests/core/AbstractCredentialsStoreTest.java b/org.eclipse.mylyn.commons.repositories.tests/src/org/eclipse/mylyn/commons/repositories/tests/core/AbstractCredentialsStoreTest.java
index c807137..e16b5b3 100644
--- a/org.eclipse.mylyn.commons.repositories.tests/src/org/eclipse/mylyn/commons/repositories/tests/core/AbstractCredentialsStoreTest.java
+++ b/org.eclipse.mylyn.commons.repositories.tests/src/org/eclipse/mylyn/commons/repositories/tests/core/AbstractCredentialsStoreTest.java
@@ -49,6 +49,17 @@ public abstract class AbstractCredentialsStoreTest {
}
@Test
+ public void testPutNull() {
+ ICredentialsStore store = createCredentialsStore();
+ store.put("key", "value", false);
+ store.put("key", null, false);
+ // putting null is different from removing a key
+ assertEquals(null, store.get("key", "default"));
+ store.remove("key");
+ assertEquals("default", store.get("key", "default"));
+ }
+
+ @Test
public void testPutGetBooleanEncrypted() {
ICredentialsStore store = createCredentialsStore();
store.putBoolean("key", true, true);
diff --git a/org.eclipse.mylyn.commons.repositories.tests/src/org/eclipse/mylyn/commons/repositories/tests/core/CertificateCredentialsTest.java b/org.eclipse.mylyn.commons.repositories.tests/src/org/eclipse/mylyn/commons/repositories/tests/core/CertificateCredentialsTest.java
new file mode 100644
index 0000000..0209478
--- /dev/null
+++ b/org.eclipse.mylyn.commons.repositories.tests/src/org/eclipse/mylyn/commons/repositories/tests/core/CertificateCredentialsTest.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Tasktop Technologies 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:
+ * Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.commons.repositories.tests.core;
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.mylyn.commons.repositories.core.auth.CertificateCredentials;
+import org.junit.Test;
+
+/**
+ * @author Steffen Pingel
+ */
+public class CertificateCredentialsTest {
+
+ @Test
+ public void testConstructor() {
+ CertificateCredentials credentials = new CertificateCredentials("filename", "password", "type");
+ assertEquals("filename", credentials.getKeyStoreFileName());
+ assertEquals("password", credentials.getPassword());
+ assertEquals("type", credentials.getKeyStoreType());
+ assertEquals(true, credentials.getSavePassword());
+ }
+
+ @Test
+ public void testConstructorSavePassword() {
+ CertificateCredentials credentials = new CertificateCredentials("filename", "password", "type", false);
+ assertEquals("filename", credentials.getKeyStoreFileName());
+ assertEquals("password", credentials.getPassword());
+ assertEquals("type", credentials.getKeyStoreType());
+ assertEquals(false, credentials.getSavePassword());
+ }
+
+}
diff --git a/org.eclipse.mylyn.commons.repositories.tests/src/org/eclipse/mylyn/commons/repositories/tests/core/CredentialsFactoryTest.java b/org.eclipse.mylyn.commons.repositories.tests/src/org/eclipse/mylyn/commons/repositories/tests/core/CredentialsFactoryTest.java
index f8509c2..0c1c540 100644
--- a/org.eclipse.mylyn.commons.repositories.tests/src/org/eclipse/mylyn/commons/repositories/tests/core/CredentialsFactoryTest.java
+++ b/org.eclipse.mylyn.commons.repositories.tests/src/org/eclipse/mylyn/commons/repositories/tests/core/CredentialsFactoryTest.java
@@ -78,7 +78,7 @@ public class CredentialsFactoryTest {
@Test
public void testSaveCertificateCredentials() throws StorageException {
ICredentialsStore store = new InMemoryCredentialsStore();
- CertificateCredentials oldCredentials = new CertificateCredentials("keyStore", "password");
+ CertificateCredentials oldCredentials = new CertificateCredentials("keyStore", "password", "type");
oldCredentials.save(store, "key");
CertificateCredentials newCredentials = CredentialsFactory.create(CertificateCredentials.class, store, "key",
true);
diff --git a/org.eclipse.mylyn.commons.repositories.tests/src/org/eclipse/mylyn/commons/repositories/tests/core/InMemoryCredentialsStoreTest.java b/org.eclipse.mylyn.commons.repositories.tests/src/org/eclipse/mylyn/commons/repositories/tests/core/InMemoryCredentialsStoreTest.java
index 4477b60..f34e664 100644
--- a/org.eclipse.mylyn.commons.repositories.tests/src/org/eclipse/mylyn/commons/repositories/tests/core/InMemoryCredentialsStoreTest.java
+++ b/org.eclipse.mylyn.commons.repositories.tests/src/org/eclipse/mylyn/commons/repositories/tests/core/InMemoryCredentialsStoreTest.java
@@ -25,6 +25,16 @@ import org.junit.Test;
public class InMemoryCredentialsStoreTest extends AbstractCredentialsStoreTest {
@Test
+ public void testCopyToNullValue() {
+ InMemoryCredentialsStore source = new InMemoryCredentialsStore();
+ InMemoryCredentialsStore target = new InMemoryCredentialsStore();
+ target.put("key", "value", false);
+ source.put("key", null, false);
+ source.copyTo(target);
+ assertEquals(null, target.get("key", null));
+ }
+
+ @Test
public void testCopyTo() {
InMemoryCredentialsStore source = new InMemoryCredentialsStore();
InMemoryCredentialsStore target = new InMemoryCredentialsStore();
diff --git a/org.eclipse.mylyn.commons.repositories.ui/src/org/eclipse/mylyn/commons/repositories/ui/RepositoryLocationPart.java b/org.eclipse.mylyn.commons.repositories.ui/src/org/eclipse/mylyn/commons/repositories/ui/RepositoryLocationPart.java
index 38a956c..38a224d 100644
--- a/org.eclipse.mylyn.commons.repositories.ui/src/org/eclipse/mylyn/commons/repositories/ui/RepositoryLocationPart.java
+++ b/org.eclipse.mylyn.commons.repositories.ui/src/org/eclipse/mylyn/commons/repositories/ui/RepositoryLocationPart.java
@@ -31,6 +31,7 @@ import org.eclipse.jface.databinding.swt.ISWTObservableValue;
import org.eclipse.jface.databinding.swt.SWTObservables;
import org.eclipse.jface.databinding.wizard.WizardPageSupport;
import org.eclipse.jface.dialogs.DialogPage;
+import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
@@ -41,6 +42,7 @@ import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.mylyn.commons.repositories.core.RepositoryLocation;
import org.eclipse.mylyn.commons.repositories.core.RepositoryValidator;
import org.eclipse.mylyn.commons.repositories.core.auth.AuthenticationType;
+import org.eclipse.mylyn.commons.repositories.core.auth.CertificateCredentials;
import org.eclipse.mylyn.commons.repositories.core.auth.UserCredentials;
import org.eclipse.mylyn.commons.workbench.forms.SectionComposite;
import org.eclipse.mylyn.internal.commons.repositories.ui.RepositoriesUiPlugin;
@@ -54,6 +56,7 @@ import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Link;
import org.eclipse.swt.widgets.Text;
@@ -79,7 +82,7 @@ public class RepositoryLocationPart {
}
- private class UsernamePasswordListener implements ModifyListener, SelectionListener {
+ private class UserCredentialsListener implements ModifyListener, SelectionListener {
private final AuthenticationType<UserCredentials> authenticationType;
@@ -97,7 +100,7 @@ public class RepositoryLocationPart {
private final Text domainText;
- public UsernamePasswordListener(AuthenticationType<UserCredentials> authenticationType, Button enabledButton,
+ public UserCredentialsListener(AuthenticationType<UserCredentials> authenticationType, Button enabledButton,
Text userText, Text passwordText, Text domainText, Button savePasswordButton) {
Assert.isNotNull(authenticationType);
Assert.isNotNull(enabledButton);
@@ -215,6 +218,116 @@ public class RepositoryLocationPart {
}
+ private class CertificateCredentialsListener implements ModifyListener, SelectionListener {
+
+ private final AuthenticationType<CertificateCredentials> authenticationType;
+
+ private final Button enabledButton;
+
+ private final Text passwordText;
+
+ private final Button savePasswordButton;
+
+ private boolean updating;
+
+ private final Text keyStoreFileNameText;
+
+ public CertificateCredentialsListener(AuthenticationType<CertificateCredentials> authenticationType,
+ Button enabledButton, Text keyStoreFileNameText, Text passwordText, Button savePasswordButton) {
+ Assert.isNotNull(authenticationType);
+ Assert.isNotNull(enabledButton);
+ Assert.isNotNull(keyStoreFileNameText);
+ Assert.isNotNull(passwordText);
+ this.authenticationType = authenticationType;
+ this.enabledButton = enabledButton;
+ this.keyStoreFileNameText = keyStoreFileNameText;
+ this.passwordText = passwordText;
+ this.savePasswordButton = savePasswordButton;
+ init();
+ }
+
+ private void apply() {
+ if (updating) {
+ return;
+ }
+ if (getEnabledButtonSelection()) {
+ CertificateCredentials credentials = new CertificateCredentials(keyStoreFileNameText.getText(),
+ passwordText.getText(), null, savePasswordButton.getSelection());
+ getWorkingCopy().setCredentials(authenticationType, credentials);
+ } else {
+ getWorkingCopy().setCredentials(authenticationType, null);
+ }
+ }
+
+ protected void init() {
+ enabledButton.addSelectionListener(this);
+ keyStoreFileNameText.addModifyListener(this);
+ passwordText.addModifyListener(this);
+ savePasswordButton.addSelectionListener(this);
+ }
+
+ protected boolean getEnabledButtonSelection() {
+ return enabledButton.getSelection();
+ }
+
+ public void modifyText(ModifyEvent event) {
+ apply();
+ }
+
+ private void restore() {
+ try {
+ updating = true;
+ CertificateCredentials credentials = getWorkingCopy().getCredentials(authenticationType);
+ if (credentials != null) {
+ enabledButton.setSelection(true);
+ keyStoreFileNameText.setText(credentials.getKeyStoreFileName());
+ passwordText.setText(credentials.getPassword());
+ savePasswordButton.setSelection(credentials.getSavePassword());
+ } else {
+ enabledButton.setSelection(false);
+ keyStoreFileNameText.setText(""); //$NON-NLS-1$
+ passwordText.setText(""); //$NON-NLS-1$
+ savePasswordButton.setSelection(true);
+ }
+ } finally {
+ updating = false;
+ }
+ updateWidgetEnablement();
+ }
+
+ private void updateWidgetEnablement() {
+ setInputFieldsEnabled(getEnabledButtonSelection());
+ }
+
+ public void widgetDefaultSelected(SelectionEvent event) {
+ apply();
+ }
+
+ public void widgetSelected(SelectionEvent event) {
+ apply();
+ if (event.widget == enabledButton) {
+ updateWidgetEnablement();
+ }
+ }
+
+ public void setEnabled(boolean enabled) {
+ if (!enabled) {
+ enabledButton.setEnabled(false);
+ setInputFieldsEnabled(false);
+ } else {
+ enabledButton.setEnabled(true);
+ updateWidgetEnablement();
+ }
+ }
+
+ private void setInputFieldsEnabled(boolean enabled) {
+ keyStoreFileNameText.setEnabled(enabled);
+ passwordText.setEnabled(enabled);
+ savePasswordButton.setEnabled(enabled);
+ }
+
+ }
+
protected static final String PREFS_PAGE_ID_NET_PROXY = "org.eclipse.ui.net.NetPreferences"; //$NON-NLS-1$
private DataBindingContext bindingContext;
@@ -229,6 +342,8 @@ public class RepositoryLocationPart {
private boolean needsValidation;
+ private boolean needsCertificateAuth;
+
private IAdaptable serviceLocator;
private final RepositoryLocation workingCopy;
@@ -237,6 +352,7 @@ public class RepositoryLocationPart {
this.workingCopy = workingCopy;
setNeedsProxy(false);
setNeedsHttpAuth(false);
+ setNeedsCertificateAuth(false);
setNeedsValidation(true);
}
@@ -269,15 +385,25 @@ public class RepositoryLocationPart {
}
}
- private UsernamePasswordListener bind(AuthenticationType<UserCredentials> authType, Button anonymousButton,
- Text userText, Text passwordText, Text domainText, Button savePasswordButton, boolean reverseEnablement) {
- UsernamePasswordListener listener = new UsernamePasswordListener(authType, anonymousButton, userText,
- passwordText, domainText, savePasswordButton);
+ private UserCredentialsListener bindUserCredentials(AuthenticationType<UserCredentials> authType,
+ Button enabledButton, Text userText, Text passwordText, Text domainText, Button savePasswordButton,
+ boolean reverseEnablement) {
+ UserCredentialsListener listener = new UserCredentialsListener(authType, enabledButton, userText, passwordText,
+ domainText, savePasswordButton);
listener.setEnablementReversed(reverseEnablement);
listener.restore();
return listener;
}
+ private CertificateCredentialsListener bindCertificateCredentials(
+ AuthenticationType<CertificateCredentials> authType, Button enabledButton, Text userText,
+ Text passwordText, Button savePasswordButton) {
+ CertificateCredentialsListener listener = new CertificateCredentialsListener(authType, enabledButton, userText,
+ passwordText, savePasswordButton);
+ listener.restore();
+ return listener;
+ }
+
protected void bind(Button button, String property) {
ISWTObservableValue uiElement = SWTObservables.observeSelection(button);
IObservableValue modelElement = new RepositoryLocationValueProperty(property, Boolean.FALSE.toString()).observe(workingCopy);
@@ -339,13 +465,16 @@ public class RepositoryLocationPart {
GridDataFactory.fillDefaults().grab(true, true).span(3, 1).applyTo(control);
}
- if (needsHttpAuth() || needsProxy() || needsAdditionalSections()) {
+ if (needsHttpAuth() || needsCertificateAuth() || needsProxy() || needsAdditionalSections()) {
SectionComposite sectionComposite = new SectionComposite(composite, SWT.NONE);
GridDataFactory.fillDefaults().grab(true, true).span(3, 1).applyTo(sectionComposite);
if (needsHttpAuth()) {
createHttpAuthSection(sectionComposite);
}
+ if (needsCertificateAuth()) {
+ createCertificateAuthSection(sectionComposite);
+ }
if (needsProxy()) {
createProxySection(sectionComposite);
}
@@ -397,7 +526,63 @@ public class RepositoryLocationPart {
Button savePasswordButton = new Button(composite, SWT.CHECK);
savePasswordButton.setText(Messages.RepositoryLocationPart_Save_Password);
- bind(AuthenticationType.HTTP, enableButton, userText, passwordText, null, savePasswordButton, false);
+ bindUserCredentials(AuthenticationType.HTTP, enableButton, userText, passwordText, null, savePasswordButton,
+ false);
+ }
+
+ private void createCertificateAuthSection(SectionComposite parent) {
+ int style = SWT.NONE;
+ if (getWorkingCopy().getCredentials(AuthenticationType.CERTIFICATE, false) != null) {
+ style |= ExpandableComposite.EXPANDED;
+ }
+ ExpandableComposite section = parent.createSection("Certificate Authentiation", style);
+ section.clientVerticalSpacing = 5;
+
+ final Composite composite = new Composite(section, SWT.NONE);
+ section.setClient(composite);
+ GridLayoutFactory.fillDefaults().numColumns(3).applyTo(composite);
+
+ Label label;
+
+ Button enableButton = new Button(composite, SWT.CHECK);
+ GridDataFactory.fillDefaults().grab(true, false).span(3, 1).applyTo(enableButton);
+ enableButton.setText("Enable certificate authentication");
+
+ label = new Label(composite, SWT.NONE);
+ label.setText("Keystore file:");
+
+ final Text keyStoreFileNameText = new Text(composite, SWT.BORDER);
+ // FIXME fix width hint
+ GridDataFactory.fillDefaults()
+ .grab(true, false)
+ .hint(IDialogConstants.ENTRY_FIELD_WIDTH, SWT.DEFAULT)
+ .applyTo(keyStoreFileNameText);
+
+ Button certBrowseButton = new Button(composite, SWT.PUSH);
+ certBrowseButton.setText("Browse...");
+ certBrowseButton.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ FileDialog fileDialog = new FileDialog(composite.getShell(), SWT.OPEN);
+ fileDialog.setFilterPath(keyStoreFileNameText.getText());
+ String fileName = fileDialog.open();
+ if (fileName != null) {
+ keyStoreFileNameText.setText(fileName);
+ }
+ }
+ });
+
+ label = new Label(composite, SWT.NONE);
+ label.setText(Messages.RepositoryLocationPart_Password);
+
+ Text passwordText = new Text(composite, SWT.BORDER | SWT.PASSWORD);
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(passwordText);
+
+ Button savePasswordButton = new Button(composite, SWT.CHECK);
+ savePasswordButton.setText(Messages.RepositoryLocationPart_Save_Password);
+
+ bindCertificateCredentials(AuthenticationType.CERTIFICATE, enableButton, keyStoreFileNameText, passwordText,
+ savePasswordButton);
}
private void createProxySection(final SectionComposite parent) {
@@ -465,8 +650,8 @@ public class RepositoryLocationPart {
Button savePasswordButton = new Button(composite, SWT.CHECK);
savePasswordButton.setText(Messages.RepositoryLocationPart_Save_Password);
- final UsernamePasswordListener listener = bind(AuthenticationType.PROXY, enableButton, userText, passwordText,
- null, savePasswordButton, false);
+ final UserCredentialsListener listener = bindUserCredentials(AuthenticationType.PROXY, enableButton, userText,
+ passwordText, null, savePasswordButton, false);
systemProxyButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
@@ -476,7 +661,7 @@ public class RepositoryLocationPart {
updateProxyEnablement(listener, proxyPortText, proxyHostText, !systemProxyButton.getSelection());
}
- protected void updateProxyEnablement(UsernamePasswordListener listener, Text hostText, Text portText,
+ protected void updateProxyEnablement(UserCredentialsListener listener, Text hostText, Text portText,
boolean selected) {
hostText.setEnabled(selected);
portText.setEnabled(selected);
@@ -534,7 +719,8 @@ public class RepositoryLocationPart {
Button savePasswordButton = new Button(parent, SWT.CHECK);
savePasswordButton.setText(Messages.RepositoryLocationPart_Save_Password);
- bind(AuthenticationType.REPOSITORY, anonymousButton, userText, passwordText, null, savePasswordButton, true);
+ bindUserCredentials(AuthenticationType.REPOSITORY, anonymousButton, userText, passwordText, null,
+ savePasswordButton, true);
}
public <T> T getContainer(Class<T> clazz) {
@@ -577,6 +763,10 @@ public class RepositoryLocationPart {
return needsAnonymousLogin;
}
+ public boolean needsCertificateAuth() {
+ return needsCertificateAuth;
+ }
+
public boolean needsHttpAuth() {
return this.needsHttpAuth;
}
@@ -601,6 +791,10 @@ public class RepositoryLocationPart {
this.needsHttpAuth = needsHttpAuth;
}
+ public void setNeedsCertificateAuth(boolean needsCertificateAuth) {
+ this.needsCertificateAuth = needsCertificateAuth;
+ }
+
public void setNeedsProxy(boolean needsProxy) {
this.needsProxy = needsProxy;
}
diff --git a/org.eclipse.mylyn.commons.repositories.ui/src/org/eclipse/mylyn/internal/commons/repositories/ui/auth/CertificateCredentialsProviderUi.java b/org.eclipse.mylyn.commons.repositories.ui/src/org/eclipse/mylyn/internal/commons/repositories/ui/auth/CertificateCredentialsProviderUi.java
index 20ad5d9..5077615 100644
--- a/org.eclipse.mylyn.commons.repositories.ui/src/org/eclipse/mylyn/internal/commons/repositories/ui/auth/CertificateCredentialsProviderUi.java
+++ b/org.eclipse.mylyn.commons.repositories.ui/src/org/eclipse/mylyn/internal/commons/repositories/ui/auth/CertificateCredentialsProviderUi.java
@@ -52,7 +52,7 @@ public class CertificateCredentialsProviderUi extends AbstractCredentialsProvide
int resultCode = dialog.open();
if (resultCode == Window.OK) {
- credentials = new CertificateCredentials(dialog.getKeyStoreFileName(), dialog.getPassword());
+ credentials = new CertificateCredentials(dialog.getKeyStoreFileName(), dialog.getPassword(), null);
request.getLocation().setCredentials(request.getAuthenticationType(), oldCredentials);
return Status.OK_STATUS;
} else {
diff --git a/org.eclipse.mylyn.commons.sdk.util/.settings/.api_filters b/org.eclipse.mylyn.commons.sdk.util/.settings/.api_filters
new file mode 100644
index 0000000..8c90200
--- /dev/null
+++ b/org.eclipse.mylyn.commons.sdk.util/.settings/.api_filters
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<component id="org.eclipse.mylyn.commons.sdk.util" version="2">
+ <resource path="src/org/eclipse/mylyn/commons/sdk/util/CommonTestUtil.java" type="org.eclipse.mylyn.commons.sdk.util.CommonTestUtil">
+ <filter id="643842064">
+ <message_arguments>
+ <message_argument value="CertificateCredentials"/>
+ <message_argument value="CommonTestUtil"/>
+ <message_argument value="getCertificateCredentials()"/>
+ </message_arguments>
+ </filter>
+ <filter id="643842064">
+ <message_arguments>
+ <message_argument value="UserCredentials"/>
+ <message_argument value="CommonTestUtil"/>
+ <message_argument value="getCredentials(CommonTestUtilPrivilegeLevel)"/>
+ </message_arguments>
+ </filter>
+ <filter id="643842064">
+ <message_arguments>
+ <message_argument value="UserCredentials"/>
+ <message_argument value="CommonTestUtil"/>
+ <message_argument value="getCredentials(CommonTestUtilPrivilegeLevel, String)"/>
+ </message_arguments>
+ </filter>
+ <filter id="643842064">
+ <message_arguments>
+ <message_argument value="UserCredentials"/>
+ <message_argument value="CommonTestUtil"/>
+ <message_argument value="getUserCredentials()"/>
+ </message_arguments>
+ </filter>
+ </resource>
+</component>
diff --git a/org.eclipse.mylyn.commons.sdk.util/META-INF/MANIFEST.MF b/org.eclipse.mylyn.commons.sdk.util/META-INF/MANIFEST.MF
index 21b574a..34b3219 100644
--- a/org.eclipse.mylyn.commons.sdk.util/META-INF/MANIFEST.MF
+++ b/org.eclipse.mylyn.commons.sdk.util/META-INF/MANIFEST.MF
@@ -11,6 +11,7 @@ Require-Bundle: org.junit,
org.eclipse.osgi,
org.eclipse.ui,
org.eclipse.mylyn.commons.core,
+ org.eclipse.mylyn.commons.repositories.core,
org.eclipse.mylyn.commons.net
Export-Package: org.eclipse.mylyn.commons.sdk.util
Bundle-Vendor: Eclipse Mylyn
diff --git a/org.eclipse.mylyn.commons.sdk.util/build.properties b/org.eclipse.mylyn.commons.sdk.util/build.properties
index 4002fdb..1d12cc7 100644
--- a/org.eclipse.mylyn.commons.sdk.util/build.properties
+++ b/org.eclipse.mylyn.commons.sdk.util/build.properties
@@ -12,6 +12,7 @@ source.. = src/
output.. = bin/
bin.includes = .,\
META-INF/,\
- about.html
+ about.html,\
+ testdata/
src.includes = about.html
jre.compilation.profile = J2SE-1.5
diff --git a/org.eclipse.mylyn.commons.sdk.util/src/org/eclipse/mylyn/commons/sdk/util/CommonTestUtil.java b/org.eclipse.mylyn.commons.sdk.util/src/org/eclipse/mylyn/commons/sdk/util/CommonTestUtil.java
index 2bc9bf6..5848557 100644
--- a/org.eclipse.mylyn.commons.sdk.util/src/org/eclipse/mylyn/commons/sdk/util/CommonTestUtil.java
+++ b/org.eclipse.mylyn.commons.sdk.util/src/org/eclipse/mylyn/commons/sdk/util/CommonTestUtil.java
@@ -1,12 +1,12 @@
/*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2011, 2012 Tasktop Technologies 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:
- * IBM Corporation - initial API and implementation
+ * Tasktop Technologies - initial API and implementation
*******************************************************************************/
package org.eclipse.mylyn.commons.sdk.util;
@@ -23,6 +23,7 @@ import java.net.URL;
import java.net.URLDecoder;
import java.nio.charset.Charset;
import java.util.Enumeration;
+import java.util.Properties;
import java.util.regex.Matcher;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
@@ -33,12 +34,23 @@ import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Plugin;
+import org.eclipse.mylyn.commons.repositories.core.auth.CertificateCredentials;
+import org.eclipse.mylyn.commons.repositories.core.auth.UserCredentials;
import org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader;
import org.eclipse.osgi.util.NLS;
+/**
+ * @author Steffen Pingel
+ */
@SuppressWarnings("restriction")
public class CommonTestUtil {
+ public enum PrivilegeLevel {
+ ADMIN, ANONYMOUS, GUEST, READ_ONLY, USER
+ }
+
+ public static final String KEY_CREDENTIALS_FILE = "mylyn.credentials";
+
private final static int MAX_RETRY = 5;
/**
@@ -146,20 +158,65 @@ public class CommonTestUtil {
}
}
- public static InputStream getResource(Object source, String filename) throws IOException {
- Class<?> clazz = (source instanceof Class<?>) ? (Class<?>) source : source.getClass();
- ClassLoader classLoader = clazz.getClassLoader();
- InputStream in = classLoader.getResourceAsStream(filename);
- if (in == null) {
- File file = getFile(source, filename);
- if (file != null) {
- return new FileInputStream(file);
+ public static CertificateCredentials getCertificateCredentials() {
+ File keyStoreFile;
+ try {
+ keyStoreFile = CommonTestUtil.getFile(CommonTestUtil.class, "testdata/keystore");
+ String password = CommonTestUtil.getUserCredentials().getPassword();
+ return new CertificateCredentials(keyStoreFile.getAbsolutePath(), password, null);
+ } catch (IOException cause) {
+ AssertionFailedError e = new AssertionFailedError("Failed to load keystore file");
+ e.initCause(cause);
+ throw e;
+ }
+ }
+
+ public static UserCredentials getCredentials(PrivilegeLevel level) {
+ return getCredentials(level, null);
+ }
+
+ public static UserCredentials getCredentials(PrivilegeLevel level, String realm) {
+ Properties properties = new Properties();
+ try {
+ File file;
+ String filename = System.getProperty(KEY_CREDENTIALS_FILE);
+ if (filename == null) {
+ try {
+ file = getFile(CommonTestUtil.class, "credentials.properties");
+ if (!file.exists()) {
+ throw new AssertionFailedError();
+ }
+ } catch (AssertionFailedError e) {
+ file = new File(new File(System.getProperty("user.home"), ".mylyn"), "credentials.properties");
+ }
+ } else {
+ file = new File(filename);
}
+ properties.load(new FileInputStream(file));
+ } catch (Exception e) {
+ AssertionFailedError error = new AssertionFailedError(
+ "must define credentials in $HOME/.mylyn/credentials.properties");
+ error.initCause(e);
+ throw error;
}
- if (in == null) {
- throw new IOException(NLS.bind("Failed to locate ''{0}'' for ''{1}''", filename, clazz.getName()));
+
+ String defaultPassword = properties.getProperty("pass");
+
+ realm = (realm != null) ? realm + "." : "";
+ switch (level) {
+ case ANONYMOUS:
+ return createCredentials(properties, realm + "anon.", "", "");
+ case GUEST:
+ return createCredentials(properties, realm + "guest.", "guest@mylyn.eclipse.org", defaultPassword);
+ case USER:
+ return createCredentials(properties, realm, "tests@mylyn.eclipse.org", defaultPassword);
+ case READ_ONLY:
+ return createCredentials(properties, realm, "read-only@mylyn.eclipse.org", defaultPassword);
+ case ADMIN:
+ return createCredentials(properties, realm + "admin.", "admin@mylyn.eclipse.org", null);
}
- return in;
+
+ throw new AssertionFailedError("invalid privilege level");
}
public static File getFile(Object source, String filename) throws IOException {
@@ -212,6 +269,26 @@ public class CommonTestUtil {
throw new AssertionFailedError("Could not locate " + filename);
}
+ public static InputStream getResource(Object source, String filename) throws IOException {
+ Class<?> clazz = (source instanceof Class<?>) ? (Class<?>) source : source.getClass();
+ ClassLoader classLoader = clazz.getClassLoader();
+ InputStream in = classLoader.getResourceAsStream(filename);
+ if (in == null) {
+ File file = getFile(source, filename);
+ if (file != null) {
+ return new FileInputStream(file);
+ }
+ }
+ if (in == null) {
+ throw new IOException(NLS.bind("Failed to locate ''{0}'' for ''{1}''", filename, clazz.getName()));
+ }
+ return in;
+ }
+
+ public static UserCredentials getUserCredentials() {
+ return getCredentials(PrivilegeLevel.USER, null);
+ }
+
public static String read(File source) throws IOException {
InputStream in = new FileInputStream(source);
try {
@@ -227,6 +304,59 @@ public class CommonTestUtil {
}
}
+ public static boolean runHeartbeatTestsOnly() {
+ return !Boolean.parseBoolean(System.getProperty("org.eclipse.mylyn.tests.all"));
+ };
+
+ /**
+ * Unzips the given zip file to the given destination directory extracting only those entries the pass through the
+ * given filter.
+ *
+ * @param zipFile
+ * the zip file to unzip
+ * @param dstDir
+ * the destination directory
+ * @throws IOException
+ * in case of problem
+ */
+ public static void unzip(ZipFile zipFile, File dstDir) throws IOException {
+ unzip(zipFile, dstDir, dstDir, 0);
+ }
+
+ public static void write(String fileName, StringBuffer content) throws IOException {
+ Writer writer = new FileWriter(fileName);
+ try {
+ writer.write(content.toString());
+ } finally {
+ try {
+ writer.close();
+ } catch (IOException e) {
+ // don't need to catch this
+ }
+ }
+ }
+
+ private static UserCredentials createCredentials(Properties properties, String prefix, String defaultUsername,
+ String defaultPassword) {
+ String username = properties.getProperty(prefix + "user");
+ String password = properties.getProperty(prefix + "pass");
+
+ if (username == null) {
+ username = defaultUsername;
+ }
+
+ if (password == null) {
+ password = defaultPassword;
+ }
+
+ if (username == null || password == null) {
+ throw new AssertionFailedError(
+ "username or password not found in <plug-in dir>/credentials.properties, make sure file is valid");
+ }
+
+ return new UserCredentials(username, password);
+ }
+
/**
* Copies all bytes in the given source stream to the given destination stream. Neither streams are closed.
*
@@ -245,21 +375,6 @@ public class CommonTestUtil {
}
}
- /**
- * Unzips the given zip file to the given destination directory extracting only those entries the pass through the
- * given filter.
- *
- * @param zipFile
- * the zip file to unzip
- * @param dstDir
- * the destination directory
- * @throws IOException
- * in case of problem
- */
- public static void unzip(ZipFile zipFile, File dstDir) throws IOException {
- unzip(zipFile, dstDir, dstDir, 0);
- }
-
private static void unzip(ZipFile zipFile, File rootDstDir, File dstDir, int depth) throws IOException {
Enumeration<? extends ZipEntry> entries = zipFile.entries();
@@ -305,17 +420,4 @@ public class CommonTestUtil {
}
}
- public static void write(String fileName, StringBuffer content) throws IOException {
- Writer writer = new FileWriter(fileName);
- try {
- writer.write(content.toString());
- } finally {
- try {
- writer.close();
- } catch (IOException e) {
- // don't need to catch this
- }
- }
- }
-
}
diff --git a/org.eclipse.mylyn.commons.sdk.util/src/org/eclipse/mylyn/commons/sdk/util/RepositoryTestFixture.java b/org.eclipse.mylyn.commons.sdk.util/src/org/eclipse/mylyn/commons/sdk/util/RepositoryTestFixture.java
new file mode 100644
index 0000000..681ad98
--- /dev/null
+++ b/org.eclipse.mylyn.commons.sdk.util/src/org/eclipse/mylyn/commons/sdk/util/RepositoryTestFixture.java
@@ -0,0 +1,160 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 Tasktop Technologies 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:
+ * Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.commons.sdk.util;
+
+import java.net.Proxy;
+import java.util.Arrays;
+import java.util.HashSet;
+
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.mylyn.commons.core.net.NetUtil;
+import org.eclipse.mylyn.commons.repositories.core.RepositoryLocation;
+import org.eclipse.mylyn.commons.repositories.core.auth.AuthenticationType;
+import org.eclipse.mylyn.commons.repositories.core.auth.UserCredentials;
+import org.eclipse.mylyn.commons.sdk.util.CommonTestUtil.PrivilegeLevel;
+
+/**
+ * @author Steffen Pingel
+ * @author Thomas Ehrnhoefer
+ */
+public abstract class RepositoryTestFixture {
+
+ private final class Activation extends TestCase {
+
+ private final boolean activate;
+
+ private Activation(String name, boolean activate) {
+ super(name);
+ this.activate = activate;
+ }
+
+ @Override
+ protected void runTest() throws Throwable {
+ if (activate) {
+ activate();
+ } else {
+ getDefault().activate();
+ }
+ }
+
+ }
+
+ private final String connectorKind;
+
+ private String description;
+
+ private String repositoryName;
+
+ private final String repositoryUrl;
+
+ private String simpleInfo;
+
+ private TestSuite suite;
+
+ public RepositoryTestFixture(String connectorKind, String repositoryUrl) {
+ this.connectorKind = connectorKind;
+ this.repositoryUrl = repositoryUrl;
+ }
+
+ public void add(Class<? extends TestCase> clazz) {
+ Assert.isNotNull(suite, "Invoke createSuite() first");
+ suite.addTestSuite(clazz);
+ }
+
+ public TestSuite createSuite(TestSuite parentSuite) {
+ suite = new TestSuite("Testing on " + getInfo());
+ parentSuite.addTest(suite);
+ suite.addTest(new Activation("repository: " + getRepositoryUrl() + " [@" + getSimpleInfo() + "]", true));
+ return suite;
+ }
+
+ public void done() {
+ Assert.isNotNull(suite, "Invoke createSuite() first");
+ suite.addTest(new Activation("done", false));
+ suite = null;
+ }
+
+ public String getConnectorKind() {
+ return connectorKind;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public String getInfo() {
+ return repositoryName + " " + simpleInfo;
+ }
+
+ public String getRepositoryUrl() {
+ return repositoryUrl;
+ }
+
+ public String getSimpleInfo() {
+ return simpleInfo;
+ }
+
+ public boolean isExcluded() {
+ String excludeFixture = System.getProperty("mylyn.test.exclude", "");
+ String[] excludeFixtureArray = excludeFixture.split(",");
+ return new HashSet<String>(Arrays.asList(excludeFixtureArray)).contains(getRepositoryUrl());
+ }
+
+ public RepositoryLocation location() throws Exception {
+ return location(PrivilegeLevel.USER);
+ }
+
+ public RepositoryLocation location(PrivilegeLevel level) throws Exception {
+ return location(level, NetUtil.getProxyForUrl(repositoryUrl));
+ }
+
+ public RepositoryLocation location(PrivilegeLevel level, Proxy proxy) throws Exception {
+ UserCredentials credentials = CommonTestUtil.getCredentials(level);
+ return location(credentials.getUserName(), credentials.getPassword(), proxy);
+ }
+
+ public RepositoryLocation location(String username, String password) throws Exception {
+ return location(username, password, NetUtil.getProxyForUrl(repositoryUrl));
+ }
+
+ public RepositoryLocation location(String username, String password, final Proxy proxy) throws Exception {
+ RepositoryLocation location = new RepositoryLocation();
+ location.setUrl(repositoryUrl);
+ location.setProxy(proxy);
+ if (username != null && password != null) {
+ location.setCredentials(AuthenticationType.REPOSITORY, new UserCredentials(username, password));
+ }
+ if (repositoryUrl.contains("/secure/")) {
+ location.setCredentials(AuthenticationType.CERTIFICATE, CommonTestUtil.getCertificateCredentials());
+ }
+ return location;
+ }
+
+ protected abstract RepositoryTestFixture activate();
+
+ protected abstract RepositoryTestFixture getDefault();
+
+ protected void setInfo(String repositoryName, String version, String description) {
+ Assert.isNotNull(repositoryName);
+ Assert.isNotNull(version);
+ this.repositoryName = repositoryName;
+ this.simpleInfo = version;
+ this.description = description;
+ if (description != null && description.length() > 0) {
+ this.simpleInfo += "/" + description;
+ }
+ }
+
+}
diff --git a/org.eclipse.mylyn.commons.sdk.util/testdata/keystore b/org.eclipse.mylyn.commons.sdk.util/testdata/keystore
new file mode 100644
index 0000000..9042435
--- /dev/null
+++ b/org.eclipse.mylyn.commons.sdk.util/testdata/keystore
Binary files differ