Bug 492968 - [USS] Provide a way to avoid the secure storage master password dialog
"Interactive" flag for the OAuth credentials provider to support
non-interactive operation and fail silently if that's not possible.
Bug: 492968
Change-Id: I249921bdcf91c8fdce78ce7010df28c89bbae0e2
Task-Url: https://bugs.eclipse.org/bugs/show_bug.cgi?id=492968
Signed-off-by: Carsten Reckord <reckord@yatta.de>
Signed-off-by: Brian de Alwis <bsd@mt.ca>
diff --git a/org.eclipse.userstorage.oauth.tests/src/org/eclipse/userstorage/oauth/EclipseOAuthCredentialsProviderTest.java b/org.eclipse.userstorage.oauth.tests/src/org/eclipse/userstorage/oauth/EclipseOAuthCredentialsProviderTest.java
index e18dc48..87b4109 100644
--- a/org.eclipse.userstorage.oauth.tests/src/org/eclipse/userstorage/oauth/EclipseOAuthCredentialsProviderTest.java
+++ b/org.eclipse.userstorage.oauth.tests/src/org/eclipse/userstorage/oauth/EclipseOAuthCredentialsProviderTest.java
@@ -1,21 +1,30 @@
package org.eclipse.userstorage.oauth;
-import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+
+import org.eclipse.userstorage.IStorageService;
+import org.eclipse.userstorage.internal.Session;
+import org.eclipse.userstorage.internal.oauth.UIFacade;
+import org.eclipse.userstorage.spi.Credentials;
+
+import org.apache.http.client.fluent.Request;
+import org.hamcrest.CoreMatchers;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mockito;
import java.net.URI;
import java.net.URISyntaxException;
-import org.apache.http.client.fluent.Request;
-import org.eclipse.userstorage.internal.Session;
-import org.eclipse.userstorage.spi.Credentials;
-import org.junit.Test;
-
public class EclipseOAuthCredentialsProviderTest {
@Test
@@ -37,24 +46,25 @@
assertFalse(provider.isValid(new Credentials("username", "")));
assertFalse(provider.isValid(new Credentials("username", "blah")));
}
-
+
@Test
public void testIsValid_ExpiredCredentials() throws URISyntaxException {
EclipseOAuthCredentialsProvider provider = new EclipseOAuthCredentialsProvider("clientId", "clientSecret",
- new String[] { "scope1", "scope2" }, new URI("http://localhost"));
+ new String[] { "scope1", "scope2" }, new URI("http://localhost"));
// expired token
- assertFalse(provider.isValid(new Credentials("username", "{\"access_token\":\"a8f8a49232520e7d621b1ae1235a35665e27344d\","
- + "\"token_type\":\"Bearer\"," + "\"scope\":\"scope1\","
- + "\"_expires_\":\"Mon, 07 Nov 2016 22:19:17 GMT\"}")));
+ assertFalse(provider.isValid(new Credentials("username",
+ "{\"access_token\":\"a8f8a49232520e7d621b1ae1235a35665e27344d\"," + "\"token_type\":\"Bearer\","
+ + "\"scope\":\"scope1\"," + "\"_expires_\":\"Mon, 07 Nov 2016 22:19:17 GMT\"}")));
}
@Test
public void testIsValid_InsufficientScope() throws URISyntaxException {
EclipseOAuthCredentialsProvider provider = new EclipseOAuthCredentialsProvider("clientId", "clientSecret",
- new String[] { "scope1", "scope2" }, new URI("http://localhost"));
+ new String[] { "scope1", "scope2" }, new URI("http://localhost"));
// expired token
- assertFalse(provider.isValid(new Credentials("username", "{\"access_token\":\"a8f8a49232520e7d621b1ae1235a35665e27344d\","
- + "\"token_type\":\"Bearer\"," + "\"scope\":\"scope1\"}")));
+ assertFalse(provider
+ .isValid(new Credentials("username", "{\"access_token\":\"a8f8a49232520e7d621b1ae1235a35665e27344d\","
+ + "\"token_type\":\"Bearer\"," + "\"scope\":\"scope1\"}")));
}
@Test
@@ -64,15 +74,50 @@
Credentials credentials = new Credentials("username", serializedForm);
EclipseOAuthCredentialsProvider provider = new EclipseOAuthCredentialsProvider("clientId", "clientSecret",
- new String[] {"scope1"}, new URI("http://localhost"));
+ new String[] { "scope1" }, new URI("http://localhost"));
assertTrue(provider.isValid(credentials));
Request request = provider.configureRequest(Request.Get("http://localhost"), new URI("http://nonsensical"),
credentials);
assertNotNull(request);
assertThat(Session.formatRequest(request),
- containsString("Authorization: Bearer a8f8a49232520e7d621b1ae1235a35665e27344d"));
+ CoreMatchers.containsString("Authorization: Bearer a8f8a49232520e7d621b1ae1235a35665e27344d"));
+ }
+
+ @Test
+ public void testProvideCredentials_nonInteractive() {
+ IStorageService service = Mockito.mock(IStorageService.class);
+
+ EclipseOAuthCredentialsProvider provider = new EclipseOAuthCredentialsProvider(
+ URI.create("http://does.not.exist"), "clientId", "clientSecret", new String[] { "scope1" },
+ URI.create("http://localhost"));
+ provider.uiFacade = Mockito.mock(UIFacade.class);
+
+ provider.setInteractive(false);
+ Credentials credential = provider.provideCredentials(service, false);
+ Mockito.verifyZeroInteractions(provider.uiFacade);
+ assertNull(credential); // should fast-exit
+ }
+
+ @Test
+ public void testProvideCredentials_interactive() {
+ IStorageService service = Mockito.mock(IStorageService.class);
+ Mockito.when(service.getServiceLabel()).thenReturn("provider");
+
+ URI authServiceURI = URI.create("http://does.not.exist");
+ URI callbackURI = URI.create("http://localhost");
+ EclipseOAuthCredentialsProvider provider = new EclipseOAuthCredentialsProvider(authServiceURI, "clientId",
+ "clientSecret", new String[] { "scope1" }, callbackURI);
+ provider.uiFacade = Mockito.mock(UIFacade.class);
+ Mockito.when(provider.uiFacade.obtainAuthCode(anyString(), any(URI.class), any(URI.class))).thenReturn(null);
+
+ assertTrue(provider.isInteractive());
+ Credentials credential = provider.provideCredentials(service, false);
+
+ assertNull(credential); // facade.obtainAuthCode => null returns null
+ ArgumentCaptor<URI> authCaptor = ArgumentCaptor.forClass(URI.class);
+ Mockito.verify(provider.uiFacade).obtainAuthCode(eq("provider"), authCaptor.capture(), eq(callbackURI));
+ assertThat(authCaptor.getValue().toString(), CoreMatchers.startsWith(authServiceURI.toString()));
}
}
-
diff --git a/org.eclipse.userstorage.oauth/src/org/eclipse/userstorage/oauth/EclipseOAuthCredentialsProvider.java b/org.eclipse.userstorage.oauth/src/org/eclipse/userstorage/oauth/EclipseOAuthCredentialsProvider.java
index 03ab911..5b23910 100644
--- a/org.eclipse.userstorage.oauth/src/org/eclipse/userstorage/oauth/EclipseOAuthCredentialsProvider.java
+++ b/org.eclipse.userstorage.oauth/src/org/eclipse/userstorage/oauth/EclipseOAuthCredentialsProvider.java
@@ -101,6 +101,8 @@
UIFacade uiFacade; // package protected for testing purposes
+ private boolean interactive = true;
+
/**
* @param clientId the OAuth identifier assigned to the application
* @param clientSecret the OAuth secret assigned to the application
@@ -159,6 +161,11 @@
return asCredentials(service, authToken);
}
}
+ if (!isInteractive())
+ {
+ debug("Non-interactive login process failed");
+ return null;
+ }
/* Start the full process */
debug("Starting OAuth authorization process");
@@ -510,4 +517,14 @@
.build();
//@formatter:on
}
+
+ public boolean isInteractive()
+ {
+ return interactive;
+ }
+
+ public void setInteractive(boolean interactive)
+ {
+ this.interactive = interactive;
+ }
}