Fix offline servlets and refactoring

This commit is contained in:
mhajas 2016-05-19 11:42:40 +02:00
parent af7fd0ef61
commit 22a94100c8
4 changed files with 73 additions and 42 deletions

View file

@ -6,12 +6,16 @@ import org.keycloak.representations.AccessToken;
import org.keycloak.representations.RefreshToken; import org.keycloak.representations.RefreshToken;
import org.keycloak.testsuite.page.AbstractPageWithInjectedUrl; import org.keycloak.testsuite.page.AbstractPageWithInjectedUrl;
import org.keycloak.util.JsonSerialization; import org.keycloak.util.JsonSerialization;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement; import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.FindBy;
import java.io.IOException; import java.io.IOException;
import java.net.URL; import java.net.URL;
import static org.keycloak.testsuite.util.WaitUtils.pause;
import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
/** /**
* @author <a href="mailto:bruno@abstractj.org">Bruno Oliveira</a>. * @author <a href="mailto:bruno@abstractj.org">Bruno Oliveira</a>.
*/ */
@ -56,4 +60,11 @@ public class OfflineToken extends AbstractPageWithInjectedUrl {
} }
return null; return null;
} }
public void logout() {
log.info("Logging out, navigating to: " + getUriBuilder().path("/logout").build().toASCIIString());
driver.navigate().to(getUriBuilder().path("/logout").build().toASCIIString());
pause(300); // this is needed for FF for some reason
waitUntilElement(By.tagName("body")).is().visible();
}
} }

View file

@ -21,8 +21,12 @@ import java.io.IOException;
*/ */
public class OfflineTokenServlet extends HttpServlet { public class OfflineTokenServlet extends HttpServlet {
private static final String OFFLINE_CLIENT_APP_URI = "http://localhost:8280/offline-client"; private static final String OFFLINE_CLIENT_APP_URI = (System.getProperty("app.server.ssl.required", "false").equals("true")) ?
private static final String ADAPTER_ROOT_URL = "http://localhost:8180"; System.getProperty("app.server.ssl.base.url", "https://localhost:8643") + "/offline-client" :
System.getProperty("app.server.base.url", "http://localhost:8280") + "/offline-client";
private static final String ADAPTER_ROOT_URL = (System.getProperty("auth.server.ssl.required", "false").equals("true")) ?
System.getProperty("auth.server.ssl.base.url", "https://localhost:8543") :
System.getProperty("auth.server.base.url", "http://localhost:8180");
@Override @Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

View file

@ -7,7 +7,6 @@ import org.junit.Assert;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.keycloak.OAuth2Constants; import org.keycloak.OAuth2Constants;
import org.keycloak.common.util.Time;
import org.keycloak.events.Details; import org.keycloak.events.Details;
import org.keycloak.events.EventType; import org.keycloak.events.EventType;
import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.RealmRepresentation;
@ -19,24 +18,27 @@ import org.keycloak.testsuite.pages.LoginPage;
import org.keycloak.testsuite.pages.OAuthGrantPage; import org.keycloak.testsuite.pages.OAuthGrantPage;
import org.keycloak.testsuite.util.ClientManager; import org.keycloak.testsuite.util.ClientManager;
import org.keycloak.util.TokenUtil; import org.keycloak.util.TokenUtil;
import org.openqa.selenium.By;
import javax.ws.rs.core.UriBuilder; import javax.ws.rs.core.UriBuilder;
import java.util.List; import java.util.List;
import static org.keycloak.testsuite.auth.page.AuthRealm.TEST; import static org.keycloak.testsuite.auth.page.AuthRealm.TEST;
import static org.keycloak.testsuite.util.IOUtil.loadRealm; import static org.keycloak.testsuite.util.IOUtil.loadRealm;
import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlDoesntStartWith;
import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWith;
import static org.keycloak.testsuite.util.WaitUtils.pause;
import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
/** /**
* @author <a href="mailto:bruno@abstractj.org">Bruno Oliveira</a>. * @author <a href="mailto:bruno@abstractj.org">Bruno Oliveira</a>.
*/ */
public abstract class AbstractOfflineServletsAdapterTest extends AbstractServletsAdapterTest { public abstract class AbstractOfflineServletsAdapterTest extends AbstractServletsAdapterTest {
private static final String OFFLINE_CLIENT_APP_URI = "http://localhost:8280/offline-client";
@Rule @Rule
public AssertEvents events = new AssertEvents(this); public AssertEvents events = new AssertEvents(this);
@Page @Page
protected OfflineToken offlineToken; protected OfflineToken offlineTokenPage;
@Page @Page
protected LoginPage loginPage; protected LoginPage loginPage;
@Page @Page
@ -64,74 +66,80 @@ public abstract class AbstractOfflineServletsAdapterTest extends AbstractServlet
@Test @Test
public void testServlet() throws Exception { public void testServlet() throws Exception {
String servletUri = UriBuilder.fromUri(OFFLINE_CLIENT_APP_URI) String servletUri = UriBuilder.fromUri(offlineTokenPage.toString())
.queryParam(OAuth2Constants.SCOPE, OAuth2Constants.OFFLINE_ACCESS) .queryParam(OAuth2Constants.SCOPE, OAuth2Constants.OFFLINE_ACCESS)
.build().toString(); .build().toString();
oauth.doLogin("test-user@localhost", "password");
driver.navigate().to(servletUri); driver.navigate().to(servletUri);
waitUntilElement(By.tagName("body")).is().visible();
Assert.assertTrue(driver.getCurrentUrl().startsWith(OFFLINE_CLIENT_APP_URI)); loginPage.login("test-user@localhost", "password");
Assert.assertEquals(offlineToken.getRefreshToken().getType(), TokenUtil.TOKEN_TYPE_OFFLINE); assertCurrentUrlStartsWith(offlineTokenPage);
Assert.assertEquals(offlineToken.getRefreshToken().getExpiration(), 0);
String accessTokenId = offlineToken.getAccessToken().getId(); Assert.assertEquals(offlineTokenPage.getRefreshToken().getType(), TokenUtil.TOKEN_TYPE_OFFLINE);
String refreshTokenId = offlineToken.getRefreshToken().getId(); Assert.assertEquals(offlineTokenPage.getRefreshToken().getExpiration(), 0);
setAdapterTimeOffset(9999); String accessTokenId = offlineTokenPage.getAccessToken().getId();
String refreshTokenId = offlineTokenPage.getRefreshToken().getId();
Assert.assertTrue(driver.getCurrentUrl().startsWith(OFFLINE_CLIENT_APP_URI)); setAdapterAndServerTimeOffset(9999);
Assert.assertNotEquals(offlineToken.getRefreshToken().getId(), refreshTokenId);
Assert.assertNotEquals(offlineToken.getAccessToken().getId(), accessTokenId); assertCurrentUrlStartsWith(offlineTokenPage);
Assert.assertNotEquals(offlineTokenPage.getRefreshToken().getId(), refreshTokenId);
Assert.assertNotEquals(offlineTokenPage.getAccessToken().getId(), accessTokenId);
// Ensure that logout works for webapp (even if offline token will be still valid in Keycloak DB) // Ensure that logout works for webapp (even if offline token will be still valid in Keycloak DB)
driver.navigate().to(OFFLINE_CLIENT_APP_URI + "/logout"); offlineTokenPage.logout();
loginPage.assertCurrent(); loginPage.assertCurrent();
driver.navigate().to(OFFLINE_CLIENT_APP_URI); offlineTokenPage.navigateTo();
loginPage.assertCurrent(); loginPage.assertCurrent();
setAdapterTimeOffset(0); setAdapterAndServerTimeOffset(0);
events.clear(); events.clear();
} }
@Test @Test
public void testServletWithRevoke() { public void testServletWithRevoke() {
// Login to servlet first with offline token // Login to servlet first with offline token
String servletUri = UriBuilder.fromUri(OFFLINE_CLIENT_APP_URI) String servletUri = UriBuilder.fromUri(offlineTokenPage.toString())
.queryParam(OAuth2Constants.SCOPE, OAuth2Constants.OFFLINE_ACCESS) .queryParam(OAuth2Constants.SCOPE, OAuth2Constants.OFFLINE_ACCESS)
.build().toString(); .build().toString();
driver.navigate().to(servletUri); driver.navigate().to(servletUri);
loginPage.login("test-user@localhost", "password"); waitUntilElement(By.tagName("body")).is().visible();
Assert.assertTrue(driver.getCurrentUrl().startsWith(OFFLINE_CLIENT_APP_URI));
Assert.assertEquals(offlineToken.getRefreshToken().getType(), TokenUtil.TOKEN_TYPE_OFFLINE); loginPage.login("test-user@localhost", "password");
assertCurrentUrlStartsWith(offlineTokenPage);
Assert.assertEquals(offlineTokenPage.getRefreshToken().getType(), TokenUtil.TOKEN_TYPE_OFFLINE);
// Assert refresh works with increased time // Assert refresh works with increased time
setAdapterTimeOffset(9999); setAdapterAndServerTimeOffset(9999);
driver.navigate().to(OFFLINE_CLIENT_APP_URI); offlineTokenPage.navigateTo();
Assert.assertTrue(driver.getCurrentUrl().startsWith(OFFLINE_CLIENT_APP_URI)); assertCurrentUrlStartsWith(offlineTokenPage);
setAdapterTimeOffset(0); setAdapterAndServerTimeOffset(0);
events.clear(); events.clear();
// Go to account service and revoke grant // Go to account service and revoke grant
accountAppPage.open(); accountAppPage.open();
List<String> additionalGrants = accountAppPage.getApplications().get("offline-client").getAdditionalGrants(); List<String> additionalGrants = accountAppPage.getApplications().get("offline-client").getAdditionalGrants();
Assert.assertEquals(additionalGrants.size(), 1); Assert.assertEquals(additionalGrants.size(), 1);
Assert.assertEquals(additionalGrants.get(0), "Offline Token"); Assert.assertEquals(additionalGrants.get(0), "Offline Token");
accountAppPage.revokeGrant("offline-client"); accountAppPage.revokeGrant("offline-client");
pause(500);
Assert.assertEquals(accountAppPage.getApplications().get("offline-client").getAdditionalGrants().size(), 0); Assert.assertEquals(accountAppPage.getApplications().get("offline-client").getAdditionalGrants().size(), 0);
events.expect(EventType.REVOKE_GRANT) events.expect(EventType.REVOKE_GRANT)
.client("account").detail(Details.REVOKED_CLIENT, "offline-client").assertEvent(); .client("account").detail(Details.REVOKED_CLIENT, "offline-client").assertEvent();
// Assert refresh doesn't work now (increase time one more time) // Assert refresh doesn't work now (increase time one more time)
setAdapterTimeOffset(9999); setAdapterAndServerTimeOffset(9999);
driver.navigate().to(OFFLINE_CLIENT_APP_URI); offlineTokenPage.navigateTo();
Assert.assertFalse(driver.getCurrentUrl().startsWith(OFFLINE_CLIENT_APP_URI)); assertCurrentUrlDoesntStartWith(offlineTokenPage);
loginPage.assertCurrent(); loginPage.assertCurrent();
setAdapterTimeOffset(0); setAdapterAndServerTimeOffset(0);
} }
@Test @Test
@ -139,24 +147,27 @@ public abstract class AbstractOfflineServletsAdapterTest extends AbstractServlet
ClientManager.realm(adminClient.realm("test")).clientId("offline-client").consentRequired(true); ClientManager.realm(adminClient.realm("test")).clientId("offline-client").consentRequired(true);
// Assert grant page doesn't have 'Offline Access' role when offline token is not requested // Assert grant page doesn't have 'Offline Access' role when offline token is not requested
driver.navigate().to(OFFLINE_CLIENT_APP_URI); offlineTokenPage.navigateTo();
loginPage.login("test-user@localhost", "password"); loginPage.login("test-user@localhost", "password");
oauthGrantPage.assertCurrent(); oauthGrantPage.assertCurrent();
Assert.assertFalse(driver.getPageSource().contains("Offline access")); waitUntilElement(By.xpath("//body")).text().not().contains("Offline access");
oauthGrantPage.cancel(); oauthGrantPage.cancel();
// Assert grant page has 'Offline Access' role now // Assert grant page has 'Offline Access' role now
String servletUri = UriBuilder.fromUri(OFFLINE_CLIENT_APP_URI) String servletUri = UriBuilder.fromUri(offlineTokenPage.toString())
.queryParam(OAuth2Constants.SCOPE, OAuth2Constants.OFFLINE_ACCESS) .queryParam(OAuth2Constants.SCOPE, OAuth2Constants.OFFLINE_ACCESS)
.build().toString(); .build().toString();
driver.navigate().to(servletUri); driver.navigate().to(servletUri);
waitUntilElement(By.tagName("body")).is().visible();
loginPage.login("test-user@localhost", "password"); loginPage.login("test-user@localhost", "password");
oauthGrantPage.assertCurrent(); oauthGrantPage.assertCurrent();
Assert.assertTrue(driver.getPageSource().contains("Offline access")); waitUntilElement(By.xpath("//body")).text().contains("Offline access");
oauthGrantPage.accept(); oauthGrantPage.accept();
Assert.assertTrue(driver.getCurrentUrl().startsWith(OFFLINE_CLIENT_APP_URI)); assertCurrentUrlStartsWith(offlineTokenPage);
Assert.assertEquals(offlineToken.getRefreshToken().getType(), TokenUtil.TOKEN_TYPE_OFFLINE); Assert.assertEquals(offlineTokenPage.getRefreshToken().getType(), TokenUtil.TOKEN_TYPE_OFFLINE);
accountAppPage.open(); accountAppPage.open();
AccountApplicationsPage.AppEntry offlineClient = accountAppPage.getApplications().get("offline-client"); AccountApplicationsPage.AppEntry offlineClient = accountAppPage.getApplications().get("offline-client");
@ -164,7 +175,7 @@ public abstract class AbstractOfflineServletsAdapterTest extends AbstractServlet
Assert.assertTrue(offlineClient.getAdditionalGrants().contains("Offline Token")); Assert.assertTrue(offlineClient.getAdditionalGrants().contains("Offline Token"));
//This was necessary to be introduced, otherwise other testcases will fail //This was necessary to be introduced, otherwise other testcases will fail
driver.navigate().to(OFFLINE_CLIENT_APP_URI + "/logout"); offlineTokenPage.logout();
loginPage.assertCurrent(); loginPage.assertCurrent();
events.clear(); events.clear();
@ -174,13 +185,15 @@ public abstract class AbstractOfflineServletsAdapterTest extends AbstractServlet
} }
private void setAdapterTimeOffset(int timeOffset) { private void setAdapterAndServerTimeOffset(int timeOffset) {
Time.setOffset(timeOffset); setTimeOffset(timeOffset);
String timeOffsetUri = UriBuilder.fromUri(OFFLINE_CLIENT_APP_URI) String timeOffsetUri = UriBuilder.fromUri(offlineTokenPage.toString())
.queryParam("timeOffset", timeOffset) .queryParam("timeOffset", timeOffset)
.build().toString(); .build().toString();
driver.navigate().to(timeOffsetUri); driver.navigate().to(timeOffsetUri);
waitUntilElement(By.tagName("body")).is().visible();
} }
} }

View file

@ -56,8 +56,11 @@
<adapter.test.props> <adapter.test.props>
-Dapp.server.base.url=http://localhost:${app.server.http.port} -Dapp.server.base.url=http://localhost:${app.server.http.port}
-Dauth.server.base.url=http://localhost:${auth.server.http.port}
-Dapp.server.ssl.base.url=https://localhost:${app.server.https.port} -Dapp.server.ssl.base.url=https://localhost:${app.server.https.port}
-Dapp.server.ssl.required=${app.server.ssl.required} -Dapp.server.ssl.required=${app.server.ssl.required}
-Dauth.server.ssl.base.url=https://localhost:${auth.server.https.port}
-Dauth.server.ssl.required=${auth.server.ssl.required}
-Dmy.host.name=localhost -Dmy.host.name=localhost
-Djava.security.krb5.conf=${project.build.directory}/dependency/kerberos/test-krb5.conf -Djava.security.krb5.conf=${project.build.directory}/dependency/kerberos/test-krb5.conf
</adapter.test.props> </adapter.test.props>