package org.syncany.tests.integration.plugins;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.core.IsInstanceOf.instanceOf;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import java.net.URI;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.syncany.plugins.transfer.StorageException;
import org.syncany.plugins.transfer.oauth.OAuthGenerator;
import org.syncany.plugins.transfer.oauth.OAuthMode;
import org.syncany.plugins.transfer.oauth.OAuthTokenExtractor;
import org.syncany.plugins.transfer.oauth.OAuthTokenExtractors;
import org.syncany.plugins.transfer.oauth.OAuthTokenFinish;
import org.syncany.plugins.transfer.oauth.OAuthTokenWebListener;
import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.ScriptException;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
/**
* @author Christian Roth <christian.roth@port17.de>
*/
public class OAuthTokenWebListenerTest {
public static final String REFERENCE_TOKEN = "aabbccddeeff";
private static final WebClient WEB_CLIENT = new WebClient(BrowserVersion.CHROME);
@BeforeClass
public static void setupWebClient() {
WEB_CLIENT.getOptions().setThrowExceptionOnFailingStatusCode(false);
}
@AfterClass
public static void closeWebClient() {
WEB_CLIENT.closeAllWindows();
}
@Test
public void testTokenAsQuery() throws Exception {
OAuthTokenWebListener twl = OAuthTokenWebListener
.forMode(OAuthMode.SERVER)
.build();
URI baseUri = twl.start();
Future<OAuthTokenFinish> submittedToken = twl.getToken();
final URI requestUri = URI.create(baseUri.toString() + "?" + OAuthTokenExtractors.RFC_CODE_FIELD + "=" + REFERENCE_TOKEN + "&" + OAuthTokenExtractors.RFC_STATE_FIELD + "=1234");
new Thread(new Runnable() {
public void run() {
try {
TimeUnit.SECONDS.sleep(2);
System.out.println("Requesting: " + requestUri);
HtmlPage page = WEB_CLIENT.getPage(requestUri.toURL());
assertEquals(200, page.getWebResponse().getStatusCode());
}
catch (ScriptException e) {
// ignore "Connection is not open"
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
}).start();
assertEquals(REFERENCE_TOKEN, submittedToken.get().getToken());
}
@Test
public void testTokenAsHash() throws Exception {
OAuthTokenWebListener twl = OAuthTokenWebListener
.forMode(OAuthMode.BROWSER)
.build();
URI baseUri = twl.start();
Future<OAuthTokenFinish> submittedToken = twl.getToken();
final URI requestUri = URI.create(baseUri.toString() + "?a=b#" + OAuthTokenExtractors.RFC_ACCESS_TOKEN_FIELD + "=" + REFERENCE_TOKEN + "&" + OAuthTokenExtractors.RFC_STATE_FIELD + "=1234");
new Thread(new Runnable() {
public void run() {
try {
TimeUnit.SECONDS.sleep(2);
System.out.println("Requesting: " + requestUri);
HtmlPage page = WEB_CLIENT.getPage(requestUri.toURL());
assertEquals(200, page.getWebResponse().getStatusCode());
}
catch (ScriptException e) {
// ignore "Connection is not open"
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
}).start();
assertEquals(REFERENCE_TOKEN, submittedToken.get().getToken());
}
@Test
public void testMissingField() throws Exception {
OAuthTokenWebListener twl = OAuthTokenWebListener
.forMode(OAuthMode.SERVER)
.build();
URI baseUri = twl.start();
Future<OAuthTokenFinish> submittedToken = twl.getToken();
final URI requestUri = URI.create(baseUri.toString() + "?" + OAuthTokenExtractors.RFC_STATE_FIELD + "=1234");
new Thread(new Runnable() {
public void run() {
try {
TimeUnit.SECONDS.sleep(2);
System.out.println("Requesting: " + requestUri);
HtmlPage page = WEB_CLIENT.getPage(requestUri.toURL());
assertEquals(400, page.getWebResponse().getStatusCode());
}
catch (ScriptException e) {
// ignore "Connection is not open"
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
}).start();
assertNull(submittedToken.get());
}
@Test
public void testOAuthGenerator() {
OAuthGenerator testOAuthGenerator = new TestOAuthGenerator();
assertThat(testOAuthGenerator, instanceOf(OAuthGenerator.class));
assertThat(testOAuthGenerator, instanceOf(OAuthGenerator.WithExtractor.class));
assertThat(testOAuthGenerator, not(instanceOf(OAuthGenerator.WithInterceptor.class)));
}
private static class TestOAuthGenerator implements OAuthGenerator, OAuthGenerator.WithExtractor {
@Override
public URI generateAuthUrl(URI redirectUri) throws StorageException {
return URI.create("http://1234/?redirect=" + redirectUri);
}
@Override
public void checkToken(String token, String csrfState) throws StorageException {
// empty
}
@Override
public OAuthTokenExtractor getExtractor() {
return OAuthTokenExtractors.newTokenExtractorForMode(OAuthMode.BROWSER);
}
}
}