keycloak-memoizeit
Changes
testsuite/integration-arquillian/servers/app-server/undertow/src/main/java/org/keycloak/testsuite/arquillian/undertow/container/UndertowDeploymentArchiveProcessor.java 2(+2 -0)
testsuite/integration-arquillian/servers/app-server/undertow/src/main/java/org/keycloak/testsuite/arquillian/undertow/UndertowAppServer.java 25(+23 -2)
testsuite/integration-arquillian/test-apps/photoz/keycloak-lazy-load-path-authz-service.json 2(+1 -1)
testsuite/integration-arquillian/test-apps/photoz/photoz-html5-client/src/main/webapp/index.html 67(+48 -19)
testsuite/integration-arquillian/test-apps/photoz/photoz-html5-client/src/main/webapp/js/app.js 256(+0 -256)
testsuite/integration-arquillian/test-apps/photoz/photoz-html5-client/src/main/webapp/js/identity.js 65(+0 -65)
testsuite/integration-arquillian/test-apps/photoz/photoz-html5-client/src/main/webapp/lib/angular/angular.min.js 214(+0 -214)
testsuite/integration-arquillian/test-apps/photoz/photoz-html5-client/src/main/webapp/lib/angular/angular-resource.min.js 13(+0 -13)
testsuite/integration-arquillian/test-apps/photoz/photoz-html5-client/src/main/webapp/lib/angular/angular-route.min.js 14(+0 -14)
testsuite/integration-arquillian/test-apps/photoz/photoz-html5-client/src/main/webapp/partials/admin/albums.html 19(+0 -19)
testsuite/integration-arquillian/test-apps/photoz/photoz-html5-client/src/main/webapp/partials/album/create.html 9(+0 -9)
testsuite/integration-arquillian/test-apps/photoz/photoz-html5-client/src/main/webapp/partials/album/detail.html 1(+0 -1)
testsuite/integration-arquillian/test-apps/photoz/photoz-html5-client/src/main/webapp/partials/home.html 22(+0 -22)
testsuite/integration-arquillian/test-apps/photoz/photoz-html5-client/src/main/webapp/partials/profile.html 6(+0 -6)
testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/src/main/java/org/keycloak/example/photoz/admin/AdminAlbumService.java 8(+3 -5)
testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/src/main/java/org/keycloak/example/photoz/album/AlbumService.java 42(+19 -23)
testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/src/main/java/org/keycloak/example/photoz/album/ProfileService.java 9(+4 -5)
testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/src/main/java/org/keycloak/example/photoz/CustomDatabase.java 88(+88 -0)
testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/src/main/java/org/keycloak/example/photoz/PhotozApplication.java 17(+16 -1)
testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/src/main/java/org/keycloak/example/photoz/unsecured/UnsecuredService.java 13(+5 -8)
testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/src/main/java/org/keycloak/example/photoz/util/Resources.java 51(+0 -51)
testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/src/main/java/org/keycloak/example/photoz/util/Transaction.java 33(+0 -33)
testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/src/main/java/org/keycloak/example/photoz/util/TransactionInterceptor.java 56(+0 -56)
testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/src/main/resources/META-INF/persistence.xml 23(+0 -23)
testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/src/main/webapp/WEB-INF/beans.xml 3(+0 -3)
testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/src/main/webapp/WEB-INF/keycloak.json 2(+1 -1)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/PhotozClientAuthzTestApp.java 240(+77 -163)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/javascript/JavascriptStateValidator.java 2(+1 -1)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/javascript/JavascriptTestExecutor.java 36(+30 -6)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/javascript/JavascriptTestExecutorWithAuthorization.java 167(+167 -0)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/javascript/JSObjectBuilder.java 2(+1 -1)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/javascript/ResponseValidator.java 2(+1 -1)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/javascript/XMLHttpRequest.java 18(+16 -2)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractPhotozExampleAdapterTest.java 565(+273 -292)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractPhotozJavascriptExecutorTest.java 108(+108 -0)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/PhotozExampleLazyLoadPathsAdapterTest.java 11(+2 -9)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/PhotozExampleNoLazyLoadPathsAdapterTest.java 10(+2 -8)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/javascript/AbstractJavascriptTest.java 2(+2 -0)
Details
diff --git a/testsuite/integration-arquillian/servers/app-server/undertow/src/main/java/org/keycloak/testsuite/arquillian/undertow/container/UndertowDeploymentArchiveProcessor.java b/testsuite/integration-arquillian/servers/app-server/undertow/src/main/java/org/keycloak/testsuite/arquillian/undertow/container/UndertowDeploymentArchiveProcessor.java
index 6b0ecf4..d812f23 100644
--- a/testsuite/integration-arquillian/servers/app-server/undertow/src/main/java/org/keycloak/testsuite/arquillian/undertow/container/UndertowDeploymentArchiveProcessor.java
+++ b/testsuite/integration-arquillian/servers/app-server/undertow/src/main/java/org/keycloak/testsuite/arquillian/undertow/container/UndertowDeploymentArchiveProcessor.java
@@ -43,6 +43,8 @@ public class UndertowDeploymentArchiveProcessor implements ApplicationArchivePro
modifySAMLAdapterConfig(archive, DeploymentArchiveProcessorUtils.SAML_ADAPTER_CONFIG_PATH);
modifySAMLAdapterConfig(archive, DeploymentArchiveProcessorUtils.SAML_ADAPTER_CONFIG_PATH_TENANT1);
modifySAMLAdapterConfig(archive, DeploymentArchiveProcessorUtils.SAML_ADAPTER_CONFIG_PATH_TENANT2);
+
+ modifyOIDCAdapterConfig(archive, DeploymentArchiveProcessorUtils.ADAPTER_CONFIG_PATH_JS);
}
private void modifyWebXML(Archive<?> archive, TestClass testClass) {
diff --git a/testsuite/integration-arquillian/servers/app-server/undertow/src/main/java/org/keycloak/testsuite/arquillian/undertow/UndertowAppServer.java b/testsuite/integration-arquillian/servers/app-server/undertow/src/main/java/org/keycloak/testsuite/arquillian/undertow/UndertowAppServer.java
index 01a4a08..b0a82de 100644
--- a/testsuite/integration-arquillian/servers/app-server/undertow/src/main/java/org/keycloak/testsuite/arquillian/undertow/UndertowAppServer.java
+++ b/testsuite/integration-arquillian/servers/app-server/undertow/src/main/java/org/keycloak/testsuite/arquillian/undertow/UndertowAppServer.java
@@ -30,6 +30,7 @@ import java.lang.reflect.Field;
import java.nio.charset.Charset;
import java.util.Collection;
import java.util.Map;
+import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
@@ -51,6 +52,7 @@ import org.jboss.logging.Logger;
import org.jboss.resteasy.plugins.server.undertow.UndertowJaxrsServer;
import org.jboss.resteasy.spi.ResteasyDeployment;
import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.Node;
import org.jboss.shrinkwrap.api.asset.ClassAsset;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.jboss.shrinkwrap.descriptor.api.Descriptor;
@@ -125,9 +127,20 @@ public class UndertowAppServer implements DeployableContainer<UndertowAppServerC
di = ((UndertowWebArchive) archive).getDeploymentInfo();
} else if (archive instanceof WebArchive) {
WebArchive webArchive = (WebArchive)archive;
+
+ Optional<Node> applicationClassNode = archive.getContent(archivePath ->
+ archivePath.get().startsWith("/WEB-INF/classes/") && archivePath.get().endsWith("Application.class"))
+ .values().stream().findFirst();
+
if (isJaxrsApp(webArchive)) {
- di = new UndertowDeployerHelper().getDeploymentInfo(configuration, webArchive,
+ di = new UndertowDeployerHelper().getDeploymentInfo(configuration, webArchive,
undertow.undertowDeployment(getCustomResteasyDeployment(webArchive)));
+ } else if (applicationClassNode.isPresent()) {
+ String applicationPath = applicationClassNode.get().getPath().get();
+
+ ResteasyDeployment deployment = new ResteasyDeployment();
+ deployment.setApplicationClass(extractClassName(applicationPath));
+ di = new UndertowDeployerHelper().getDeploymentInfo(configuration, (WebArchive) archive, undertow.undertowDeployment(deployment));
} else {
di = new UndertowDeployerHelper().getDeploymentInfo(configuration, webArchive);
}
@@ -155,6 +168,14 @@ public class UndertowAppServer implements DeployableContainer<UndertowAppServerC
createHttpContextForDeploymentInfo(di));
}
+ private String extractClassName(String applicationPath) {
+ applicationPath = applicationPath
+ .substring(0, applicationPath.lastIndexOf(".class")) // Remove .class
+ .replaceFirst("^/WEB-INF/classes/", ""); // Remove /WEB-INF/classes/ from beginning
+
+ return applicationPath.replaceAll("/", ".");
+ }
+
@Override
public void undeploy(Archive<?> archive) throws DeploymentException {
log.info("Undeploying archive " + archive.getName());
@@ -218,7 +239,7 @@ public class UndertowAppServer implements DeployableContainer<UndertowAppServerC
private ResteasyDeployment getCustomResteasyDeployment(WebArchive webArchive) {
//take all classes from war and add those with @Path annotation to RestSamlApplicationConfig
- Set<Class<?>> classes = webArchive.getContent(archivePath ->
+ Set<Class<?>> classes = webArchive.getContent(archivePath ->
archivePath.get().startsWith("/WEB-INF/classes/") &&
archivePath.get().endsWith(".class")
).values().stream()
diff --git a/testsuite/integration-arquillian/test-apps/photoz/keycloak-lazy-load-path-authz-service.json b/testsuite/integration-arquillian/test-apps/photoz/keycloak-lazy-load-path-authz-service.json
index 47437dc..9eaf990 100644
--- a/testsuite/integration-arquillian/test-apps/photoz/keycloak-lazy-load-path-authz-service.json
+++ b/testsuite/integration-arquillian/test-apps/photoz/keycloak-lazy-load-path-authz-service.json
@@ -32,7 +32,7 @@
},
{
"name" : "Album Resource",
- "path" : "/album/{id}",
+ "path" : "/album/{id}/",
"methods" : [
{
"method": "DELETE",
diff --git a/testsuite/integration-arquillian/test-apps/photoz/photoz-html5-client/src/main/webapp/index.html b/testsuite/integration-arquillian/test-apps/photoz/photoz-html5-client/src/main/webapp/index.html
index a66fcdc..f604cb4 100755
--- a/testsuite/integration-arquillian/test-apps/photoz/photoz-html5-client/src/main/webapp/index.html
+++ b/testsuite/integration-arquillian/test-apps/photoz/photoz-html5-client/src/main/webapp/index.html
@@ -5,34 +5,63 @@
<meta charset="utf-8">
<title>Photoz HTML5 Client</title>
- <!-- Load AngularJS -->
- <script src="lib/angular/angular.min.js"></script>
- <script src="lib/angular/angular-resource.min.js"></script>
- <script src="lib/angular/angular-route.min.js"></script>
<script src="lib/jwt-decode.min.js"></script>
<script src="http://localhost:8180/auth/js/keycloak.js"></script>
<script src="http://localhost:8180/auth/js/keycloak-authz.js"></script>
- <script src="js/identity.js" type="text/javascript"></script>
- <script src="js/app.js" type="text/javascript"></script>
</head>
-<body data-ng-controller="TokenCtrl">
+<h2>Result</h2>
+<pre style="background-color: #ddd; border: 1px solid #ccc; padding: 10px;" id="output"></pre>
-<!--<a href data-ng-click="showRpt()">Show Requesting Party Token </a> | <a href data-ng-click="showAccessToken()">Show Access Token </a> | <a href data-ng-click="requestEntitlements()">Request Entitlements</a> | <a href data-ng-click="requestEntitlement()">Request Entitlement</a> |<a href="" ng-click="Identity.logout()">Sign Out</a>-->
-<a href data-ng-click="showRpt()">Show Requesting Party Token </a> |
-<a href data-ng-click="showAccessToken()">Show Access Token </a> |
-<a id="entitlements" href data-ng-click="requestEntitlements()">Request Entitlements</a> |
-<a id="entitlement" href data-ng-click="requestEntitlement()">Request Entitlement</a> |
-<a id="my-account" href ng-click="Identity.account()">My Account</a> |
-<a href="" ng-click="Identity.logout()">Sign Out</a>
+<h2>Events</h2>
+<pre style="background-color: #ddd; border: 1px solid #ccc; padding: 10px;" id="events"></pre>
-<div id="content-area" class="col-md-9" role="main">
- <div id="content" ng-view/>
-</div>
-<div style="display: none;" id="bearer"></div>
-<pre style="background-color: #ddd; border: 1px solid #ccc; padding: 10px;" id="output"></pre>
+<script>
+ function showExpires() {
+ if (!keycloak.tokenParsed) {
+ output("Not authenticated");
+ return;
+ }
+
+ var o = 'Token Expires:\t\t' + new Date((keycloak.tokenParsed.exp + keycloak.timeSkew) * 1000).toLocaleString() + '\n';
+ o += 'Token Expires in:\t' + Math.round(keycloak.tokenParsed.exp + keycloak.timeSkew - new Date().getTime() / 1000) + ' seconds\n';
+
+ if (keycloak.refreshTokenParsed) {
+ o += 'Refresh Token Expires:\t' + new Date((keycloak.refreshTokenParsed.exp + keycloak.timeSkew) * 1000).toLocaleString() + '\n';
+ o += 'Refresh Expires in:\t' + Math.round(keycloak.refreshTokenParsed.exp + keycloak.timeSkew - new Date().getTime() / 1000) + ' seconds';
+ }
+
+ output(o);
+ }
+
+ function showError() {
+ output("Error: " + getParameterByName("error") + "\n" + "Error description: " + getParameterByName("error_description"));
+ }
+
+ function getParameterByName(name, url) {
+ if (!url) url = window.location.href;
+ name = name.replace(/[\[\]]/g, "\\$&");
+ var regex = new RegExp("[?&#]" + name + "(=([^&#]*)|&|#|$)"),
+ results = regex.exec(url);
+ if (!results) return null;
+ if (!results[2]) return '';
+ return decodeURIComponent(results[2].replace(/\+/g, " "));
+ }
+
+ function output(data) {
+ if (typeof data === 'object') {
+ data = JSON.stringify(data, null, ' ');
+ }
+ document.getElementById('output').innerHTML = data;
+ }
+
+ function event(event) {
+ var e = document.getElementById('events').innerHTML;
+ document.getElementById('events').innerHTML = new Date().toLocaleString() + "\t" + event + "\n" + e;
+ }
+</script>
</body>
</html>
diff --git a/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/pom.xml b/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/pom.xml
index e06fe64..5f1c150 100755
--- a/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/pom.xml
+++ b/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/pom.xml
@@ -70,6 +70,14 @@
<skip>false</skip>
</configuration>
</plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-war-plugin</artifactId>
+ <version>3.0.0</version>
+ <configuration>
+ <attachClasses>true</attachClasses>
+ </configuration>
+ </plugin>
</plugins>
</build>
</project>
diff --git a/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/src/main/java/org/keycloak/example/photoz/admin/AdminAlbumService.java b/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/src/main/java/org/keycloak/example/photoz/admin/AdminAlbumService.java
index 22b5388..dff162c 100644
--- a/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/src/main/java/org/keycloak/example/photoz/admin/AdminAlbumService.java
+++ b/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/src/main/java/org/keycloak/example/photoz/admin/AdminAlbumService.java
@@ -17,10 +17,9 @@
*/
package org.keycloak.example.photoz.admin;
+import org.keycloak.example.photoz.CustomDatabase;
import org.keycloak.example.photoz.entity.Album;
-import javax.inject.Inject;
-import javax.persistence.EntityManager;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
@@ -39,8 +38,7 @@ public class AdminAlbumService {
public static final String SCOPE_ADMIN_ALBUM_MANAGE = "admin:manage";
- @Inject
- private EntityManager entityManager;
+ private CustomDatabase entityManager = CustomDatabase.create();
@Context
private HttpHeaders headers;
@@ -49,7 +47,7 @@ public class AdminAlbumService {
@Produces("application/json")
public Response findAll() {
HashMap<String, List<Album>> albums = new HashMap<>();
- List<Album> result = this.entityManager.createQuery("from Album").getResultList();
+ List<Album> result = this.entityManager.getAll();
for (Album album : result) {
//We need to compile this under JDK7 so we can't use lambdas
diff --git a/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/src/main/java/org/keycloak/example/photoz/album/AlbumService.java b/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/src/main/java/org/keycloak/example/photoz/album/AlbumService.java
index 40b1242..4e62e1e 100644
--- a/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/src/main/java/org/keycloak/example/photoz/album/AlbumService.java
+++ b/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/src/main/java/org/keycloak/example/photoz/album/AlbumService.java
@@ -3,14 +3,12 @@ package org.keycloak.example.photoz.album;
import org.keycloak.KeycloakSecurityContext;
import org.keycloak.authorization.client.AuthzClient;
import org.keycloak.authorization.client.ClientAuthorizationContext;
+import org.keycloak.example.photoz.CustomDatabase;
+import org.keycloak.example.photoz.entity.Album;
import org.keycloak.representations.idm.authorization.ResourceRepresentation;
import org.keycloak.representations.idm.authorization.ScopeRepresentation;
import org.keycloak.authorization.client.resource.ProtectionResource;
-import org.keycloak.example.photoz.entity.Album;
-import org.keycloak.example.photoz.util.Transaction;
-import javax.inject.Inject;
-import javax.persistence.EntityManager;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
@@ -29,7 +27,6 @@ import javax.ws.rs.core.HttpHeaders;
import org.jboss.logging.Logger;
@Path("/album")
-@Transaction
public class AlbumService {
private final Logger log = Logger.getLogger(AlbumService.class);
@@ -37,8 +34,7 @@ public class AlbumService {
public static final String SCOPE_ALBUM_VIEW = "album:view";
public static final String SCOPE_ALBUM_DELETE = "album:delete";
- @Inject
- private EntityManager entityManager;
+ private CustomDatabase customDatabase = CustomDatabase.create();
@Context
private HttpServletRequest request;
@@ -57,28 +53,28 @@ public class AlbumService {
newAlbum.setUserId(userId);
log.debug("PERSISTING " + newAlbum);
- entityManager.persist(newAlbum);
+ customDatabase.addAlbum(newAlbum);
try {
createProtectedResource(newAlbum);
} catch (RuntimeException e) {
log.debug("ERROR " + e);
- entityManager.remove(newAlbum);
- throw e;
+ customDatabase.remove(newAlbum);
+ return Response.status(500).entity(e.getMessage()).build(); //
}
return Response.ok(newAlbum).build();
}
- @Path("{id}")
+ @Path("{name}")
@DELETE
- public Response delete(@PathParam("id") String id, @Context HttpHeaders headers) {
+ public Response delete(@PathParam("name") String name, @Context HttpHeaders headers) {
printAuthHeaders(headers);
- Album album = this.entityManager.find(Album.class, Long.valueOf(id));
+ Album album = this.customDatabase.findByName(name);
try {
deleteProtectedResource(album);
- this.entityManager.remove(album);
+ this.customDatabase.remove(album);
} catch (Exception e) {
throw new RuntimeException("Could not delete album.", e);
}
@@ -90,23 +86,23 @@ public class AlbumService {
@Produces("application/json")
public Response findAll(@QueryParam("getAll") Boolean getAll) {
if (getAll != null && getAll) {
- return Response.ok(this.entityManager.createQuery("from Album").getResultList()).build();
+ return Response.ok(this.customDatabase.getAll()).build();
} else {
- return Response.ok(this.entityManager.createQuery("from Album where userId = '" + request.getUserPrincipal().getName() + "'").getResultList()).build();
+ return Response.ok(this.customDatabase.findByUserId(request.getUserPrincipal().getName())).build();
}
}
@GET
- @Path("{id}")
+ @Path("{name}")
@Produces("application/json")
- public Response findById(@PathParam("id") String id) {
- List result = this.entityManager.createQuery("from Album where id = " + Long.valueOf(id)).getResultList();
+ public Response findById(@PathParam("name") String name) {
+ Album result = this.customDatabase.findByName(name);
- if (result.isEmpty()) {
+ if (result == null) {
return Response.status(Status.NOT_FOUND).build();
}
- return Response.ok(result.get(0)).build();
+ return Response.ok(result).build();
}
private void createProtectedResource(Album album) {
@@ -117,7 +113,7 @@ public class AlbumService {
scopes.add(new ScopeRepresentation(SCOPE_ALBUM_VIEW));
scopes.add(new ScopeRepresentation(SCOPE_ALBUM_DELETE));
- ResourceRepresentation albumResource = new ResourceRepresentation(album.getName(), scopes, "/album/" + album.getId(), "http://photoz.com/album");
+ ResourceRepresentation albumResource = new ResourceRepresentation(album.getName(), scopes, "/album/" + album.getName(), "http://photoz.com/album");
albumResource.setOwner(album.getUserId());
@@ -132,7 +128,7 @@ public class AlbumService {
}
private void deleteProtectedResource(Album album) {
- String uri = "/album/" + album.getId();
+ String uri = "/album/" + album.getName();
try {
ProtectionResource protection = getAuthzClient().protection();
diff --git a/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/src/main/java/org/keycloak/example/photoz/album/ProfileService.java b/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/src/main/java/org/keycloak/example/photoz/album/ProfileService.java
index 6e3e3b0..4d66499 100644
--- a/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/src/main/java/org/keycloak/example/photoz/album/ProfileService.java
+++ b/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/src/main/java/org/keycloak/example/photoz/album/ProfileService.java
@@ -17,8 +17,8 @@
*/
package org.keycloak.example.photoz.album;
-import javax.inject.Inject;
-import javax.persistence.EntityManager;
+import org.keycloak.example.photoz.CustomDatabase;
+
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
@@ -36,14 +36,13 @@ public class ProfileService {
private static final String PROFILE_VIEW = "profile:view";
- @Inject
- private EntityManager entityManager;
+ private CustomDatabase customDatabase = CustomDatabase.create();
@GET
@Produces("application/json")
public Response view(@Context HttpServletRequest request) {
Principal userPrincipal = request.getUserPrincipal();
- List albums = this.entityManager.createQuery("from Album where userId = '" + userPrincipal.getName() + "'").getResultList();
+ List albums = this.customDatabase.findByUserId(userPrincipal.getName());
return Response.ok(new Profile(userPrincipal.getName(), albums.size())).build();
}
diff --git a/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/src/main/java/org/keycloak/example/photoz/CustomDatabase.java b/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/src/main/java/org/keycloak/example/photoz/CustomDatabase.java
new file mode 100644
index 0000000..9c06eff
--- /dev/null
+++ b/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/src/main/java/org/keycloak/example/photoz/CustomDatabase.java
@@ -0,0 +1,88 @@
+package org.keycloak.example.photoz;
+
+import org.keycloak.example.photoz.entity.Album;
+import org.keycloak.example.photoz.entity.Photo;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * @author mhajas
+ */
+public class CustomDatabase {
+
+ private static final CustomDatabase INSTANCE = new CustomDatabase();
+ private List<Album> albums;
+ private List<Photo> photos;
+ private Long lastIndex = 0L;
+
+
+ public static final CustomDatabase create() {
+ return INSTANCE;
+ }
+
+ private CustomDatabase() {
+ albums = new ArrayList<>();
+ }
+
+ public List<Album> getAll() {
+ return albums;
+ }
+
+ public void addAlbum(Album a) {
+ a.setId(lastIndex++);
+ albums.add(a);
+ }
+
+ public void remove(Album albumToRemove) {
+ Iterator<Album> iter = albums.iterator();
+
+ while (iter.hasNext()) {
+ Album a = iter.next();
+ if (a.getId().equals(albumToRemove.getId())) {
+ iter.remove();
+ }
+ }
+ }
+
+ public Album findById(Long id) {
+ for (Album a : albums) {
+ if(a.getId().equals(id)) {
+ return a;
+ }
+ }
+
+ return null;
+ }
+
+ public Album findByName(String name) {
+ for (Album a : albums) {
+ if(a.getName().equals(name)) {
+ return a;
+ }
+ }
+
+ return null;
+ }
+
+ public List<Album> findByUserId(String userId) {
+ List<Album> result = new ArrayList<>();
+
+ for (Album a : albums) {
+ if (a.getUserId().equals(userId)) {
+ result.add(a);
+ }
+ }
+
+ return result;
+ }
+
+ public int cleanAll() {
+ int result = albums.size() + photos.size();
+ albums.clear();
+ photos.clear();
+
+ return result;
+ }
+}
diff --git a/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/src/main/java/org/keycloak/example/photoz/PhotozApplication.java b/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/src/main/java/org/keycloak/example/photoz/PhotozApplication.java
index 5b8377c..90e0951 100644
--- a/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/src/main/java/org/keycloak/example/photoz/PhotozApplication.java
+++ b/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/src/main/java/org/keycloak/example/photoz/PhotozApplication.java
@@ -1,12 +1,27 @@
package org.keycloak.example.photoz;
+import org.keycloak.example.photoz.admin.AdminAlbumService;
+import org.keycloak.example.photoz.album.AlbumService;
+import org.keycloak.example.photoz.album.ProfileService;
+import org.keycloak.example.photoz.unsecured.UnsecuredService;
+
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
+import java.util.LinkedHashSet;
+import java.util.Set;
/**
* Basic auth app.
*/
@ApplicationPath("/")
public class PhotozApplication extends Application {
-
+ @Override
+ public Set<Class<?>> getClasses() {
+ Set<Class<?>> resources = new LinkedHashSet<Class<?>>();
+ resources.add(AlbumService.class);
+ resources.add(AdminAlbumService.class);
+ resources.add(ProfileService.class);
+ resources.add(UnsecuredService.class);
+ return resources;
+ }
}
diff --git a/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/src/main/java/org/keycloak/example/photoz/unsecured/UnsecuredService.java b/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/src/main/java/org/keycloak/example/photoz/unsecured/UnsecuredService.java
index ff07d37..8991ea9 100644
--- a/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/src/main/java/org/keycloak/example/photoz/unsecured/UnsecuredService.java
+++ b/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/src/main/java/org/keycloak/example/photoz/unsecured/UnsecuredService.java
@@ -17,13 +17,12 @@
package org.keycloak.example.photoz.unsecured;
-import javax.inject.Inject;
-import javax.persistence.EntityManager;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Response;
import javax.ws.rs.GET;
import org.jboss.logging.Logger;
+import org.keycloak.example.photoz.CustomDatabase;
/**
* Service used to ensure there is clean DB before test
@@ -35,17 +34,15 @@ public class UnsecuredService {
private final Logger log = Logger.getLogger(UnsecuredService.class);
- @Inject
- private EntityManager entityManager;
+ private CustomDatabase customDatabase = CustomDatabase.create();
@GET
@Produces("application/json")
public Response cleanAll() {
- int deletedAlbums = entityManager.createQuery("delete from Album").executeUpdate();
- int deletedPhotos = entityManager.createQuery("delete from Photo").executeUpdate();
+ int deleted = customDatabase.cleanAll();
- if (deletedAlbums != 0 || deletedPhotos != 0) {
- log.warnf("Database was not empty. Deleted {0} Albums, {1} Photos", deletedAlbums, deletedPhotos);
+ if (deleted != 0) {
+ log.warnf("Database was not empty. Deleted Albums + Photos {0}", deleted);
} else {
log.debug("Database was clean before test");
}
diff --git a/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/src/main/webapp/WEB-INF/beans.xml b/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/src/main/webapp/WEB-INF/beans.xml
index fbf2a32..cf30c7d 100644
--- a/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/src/main/webapp/WEB-INF/beans.xml
+++ b/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/src/main/webapp/WEB-INF/beans.xml
@@ -3,7 +3,4 @@
xsi:schemaLocation="
http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
- <interceptors>
- <class>org.keycloak.example.photoz.util.TransactionInterceptor</class>
- </interceptors>
</beans>
diff --git a/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/src/main/webapp/WEB-INF/keycloak.json b/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/src/main/webapp/WEB-INF/keycloak.json
index dd0cab1..2b03024 100644
--- a/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/src/main/webapp/WEB-INF/keycloak.json
+++ b/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/src/main/webapp/WEB-INF/keycloak.json
@@ -31,7 +31,7 @@
},
{
"name" : "Album Resource",
- "path" : "/album/{id}",
+ "path" : "/album/{id}/",
"methods" : [
{
"method": "DELETE",
diff --git a/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api-authz-service.json b/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api-authz-service.json
index 7327cba..ffb7126 100644
--- a/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api-authz-service.json
+++ b/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api-authz-service.json
@@ -99,7 +99,7 @@
"decisionStrategy": "UNANIMOUS",
"config": {
"applyPolicies": "[]",
- "code": "var contextAttributes = $evaluation.getContext().getAttributes();\n\nif (contextAttributes.containsValue('kc.client.network.ip_address', '127.0.0.1')) {\n $evaluation.grant();\n}"
+ "code": "var contextAttributes = $evaluation.getContext().getAttributes();\n\nif (contextAttributes.containsValue('kc.client.network.ip_address', '127.0.0.1') || contextAttributes.containsValue('kc.client.network.ip_address', '0:0:0:0:0:0:0:1')) {\n $evaluation.grant();\n}"
}
},
{
diff --git a/testsuite/integration-arquillian/tests/base/pom.xml b/testsuite/integration-arquillian/tests/base/pom.xml
index db9afca..768558e 100644
--- a/testsuite/integration-arquillian/tests/base/pom.xml
+++ b/testsuite/integration-arquillian/tests/base/pom.xml
@@ -86,6 +86,12 @@
<scope>compile</scope>
</dependency>
<dependency>
+ <groupId>org.assertj</groupId>
+ <artifactId>assertj-core</artifactId>
+ <version>3.11.1</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
<groupId>org.subethamail</groupId>
<artifactId>subethasmtp</artifactId>
<scope>compile</scope>
@@ -139,12 +145,8 @@
<dependency>
<groupId>org.keycloak.testsuite</groupId>
<artifactId>photoz-restful-api</artifactId>
- <type>war</type>
<version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.hibernate</groupId>
- <artifactId>hibernate-c3p0</artifactId>
+ <classifier>classes</classifier>
</dependency>
</dependencies>
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/PhotozClientAuthzTestApp.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/PhotozClientAuthzTestApp.java
index 9db6c25..0a1a8ee 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/PhotozClientAuthzTestApp.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/PhotozClientAuthzTestApp.java
@@ -22,10 +22,13 @@ import org.jboss.arquillian.graphene.page.Page;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.keycloak.testsuite.auth.page.login.OIDCLogin;
import org.keycloak.testsuite.page.AbstractPageWithInjectedUrl;
-import org.keycloak.testsuite.pages.ConsentPage;
import org.keycloak.testsuite.util.JavascriptBrowser;
import org.keycloak.testsuite.util.UIUtils;
import org.keycloak.testsuite.util.URLUtils;
+import org.keycloak.testsuite.util.javascript.JavascriptStateValidator;
+import org.keycloak.testsuite.util.javascript.JavascriptTestExecutorWithAuthorization;
+import org.keycloak.testsuite.util.javascript.ResponseValidator;
+import org.keycloak.testsuite.util.javascript.XMLHttpRequest;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
@@ -33,8 +36,6 @@ import org.openqa.selenium.support.FindBy;
import java.net.URL;
-import static org.hamcrest.Matchers.containsString;
-import static org.junit.Assert.assertThat;
import static org.keycloak.testsuite.util.UIUtils.clickLink;
import static org.keycloak.testsuite.util.WaitUtils.pause;
import static org.keycloak.testsuite.util.WaitUtils.waitForPageToLoad;
@@ -61,9 +62,6 @@ public class PhotozClientAuthzTestApp extends AbstractPageWithInjectedUrl {
@JavascriptBrowser
protected OIDCLogin loginPage;
- @Page
- @JavascriptBrowser
- protected ConsentPage consentPage;
@FindBy(xpath = "//a[@ng-click = 'Identity.logout()']")
@JavascriptBrowser
@@ -85,74 +83,59 @@ public class PhotozClientAuthzTestApp extends AbstractPageWithInjectedUrl {
@JavascriptBrowser
private WebElement output;
+ private JavascriptTestExecutorWithAuthorization testExecutor;
+ private String apiUrl;
+
+ public void setTestExecutorPlayground(JavascriptTestExecutorWithAuthorization executor, String apiUrl) {
+ testExecutor = executor;
+ this.apiUrl = apiUrl;
+ }
+
public void createAlbum(String name) {
createAlbum(name, false);
}
public void createAlbum(String name, boolean managed) {
- if (managed) {
- createAlbum(name, "save-managed-album");
- } else {
- createAlbum(name, "save-album");
- }
+ createAlbum(name, managed, false, null);
}
- public void createAlbum(String name, String buttonId) {
- log.debugf("Creating album {0} with buttonId: {1}", name, buttonId);
- navigateTo();
- WebElement createAlbum = driver.findElement(By.id("create-album"));
- waitUntilElement(createAlbum).is().clickable();
- createAlbum.click();
- WebElement albumNameInput = driver.findElement(By.id("album.name"));
- waitUntilElement(albumNameInput).is().present();
- UIUtils.setTextInputValue(albumNameInput, name);
- waitUntilElement(albumNameInput).attribute(UIUtils.VALUE_ATTR_NAME).contains(name);
- WebElement button = driver.findElement(By.id(buttonId));
- waitUntilElement(button).is().clickable();
- button.click();
- pause(WAIT_AFTER_OPERATION);
- if (buttonId.equals("save-album-invalid")) {
- waitForPageToLoad();
- assertThat(driver.getPageSource(), containsString("Could not register protected resource."));
- } else {
- waitUntilElement(albumNameInput).is().not().present();
- }
+ public void createAlbum(String name, boolean managed, boolean invalidUser, ResponseValidator validator) {
+ testExecutor.sendXMLHttpRequest(
+ XMLHttpRequest.create()
+ .method("POST")
+ .url(apiUrl + "/album" + (invalidUser ? "?user=invalidUser" : ""))
+ .content("JSON.stringify(JSON.parse('{\"name\" : \"" + name + "\", \"userManaged\": " + Boolean.toString(managed) + " }'))")
+ .addHeader("Content-Type", "application/json; charset=UTF-8")
+ , validator);
}
- public void createAlbumWithInvalidUser(String name) {
- createAlbum(name, "save-album-invalid");
+
+ public void createAlbumWithInvalidUser(String name, ResponseValidator validator) {
+ createAlbum(name, false, true, validator);
}
+
+
@Override
public URL getInjectedUrl() {
return this.url;
}
- public void deleteAlbum(String name, boolean shouldBeDenied) {
- log.debugf("Deleting album {0}", name);
- WebElement delete = driver.findElement(By.id("delete-" + name));
- waitUntilElement(delete).is().clickable();
- delete.click();
- pause(WAIT_AFTER_OPERATION);
- if (shouldBeDenied) {
- waitForDenial();
- } else {
- waitUntilElement(delete).is().not().present();
- }
+ public void deleteAlbum(String name, ResponseValidator validator) {
+ testExecutor.sendXMLHttpRequest(
+ XMLHttpRequest.create()
+ .method("DELETE")
+ .url(apiUrl + "/album/" + name + "/") // it doesn't work without ending "/"
+ , validator);
}
- public void navigateToAdminAlbum(boolean shouldBeDenied) {
- log.debug("Navigating to Admin Album");
- URLUtils.navigateToUri(toString() + "/#/admin/album");
-
- driver.navigate().refresh(); // This is sometimes necessary for loading the new policy settings
- waitForPageToLoad();
- pause(WAIT_AFTER_OPERATION);
- if (shouldBeDenied) {
- waitForDenial();
- } else {
- waitUntilElement(output).text().equalTo("");
- }
+ public void navigateToAdminAlbum(ResponseValidator validator) {
+ testExecutor.sendXMLHttpRequest(
+ XMLHttpRequest.create()
+ .method("GET")
+ .addHeader("Accept", "application/json")
+ .url(apiUrl + "/admin/album")
+ , validator);
}
public void logOut() {
@@ -161,73 +144,24 @@ public class PhotozClientAuthzTestApp extends AbstractPageWithInjectedUrl {
clickLink(signOutButton);
}
- public void requestEntitlement() {
- waitUntilElement(entitlement).is().clickable();
- entitlement.click();
- waitForPageToLoad();
- pause(WAIT_AFTER_OPERATION);
- pause(WAIT_AFTER_OPERATION);
+ public void requestEntitlement(JavascriptStateValidator validator) {
+ testExecutor.executeAsyncScript("var callback = arguments[arguments.length - 1];" +
+ "window.authorization.entitlement('photoz-restful-api', {" +
+ " \"permissions\": [" +
+ " {" +
+ " \"id\" : \"Album Resource\"" +
+ " }" +
+ " ]" +
+ "}).then(function (rpt) {" +
+ " callback(JSON.stringify(jwt_decode(rpt), null, ' '));" +
+ "});", validator);
}
- public void requestEntitlements() {
- waitUntilElement(entitlements).is().clickable();
- entitlements.click();
- waitForPageToLoad();
- pause(WAIT_AFTER_OPERATION);
- pause(WAIT_AFTER_OPERATION);
- }
-
- public void login(String username, String password, String... scopes) throws InterruptedException {
- String currentUrl = this.driver.getCurrentUrl();
-
- if (scopes.length > 0) {
- StringBuilder scopesValue = new StringBuilder();
-
- for (String scope : scopes) {
- if (scopesValue.length() != 0) {
- scopesValue.append(" ");
- }
- scopesValue.append(scope);
- }
-
- scopesValue.append(" openid");
-
-
- StringBuilder urlWithScopeParam = new StringBuilder(currentUrl);
-
- int scopeIndex = currentUrl.indexOf("scope");
-
- if (scopeIndex != -1) {
- // Remove scope param from url
- urlWithScopeParam.delete(scopeIndex, currentUrl.indexOf('&', scopeIndex));
- // Add scope param to the end of query
- urlWithScopeParam.append("&").append("scope=");
- }
-
- if (!currentUrl.contains("?")) {
- urlWithScopeParam.append("?scope=");
- }
-
- urlWithScopeParam.append(scopesValue);
-
- URLUtils.navigateToUri(urlWithScopeParam.toString());
- }
-
- this.loginPage.form().login(username, password);
- waitForPageToLoad();//guess
-
- try {
- if (!isCurrent()) {
- // simple check if we are at the consent page, if so just click 'Yes'
- if (this.consentPage.isCurrent(driver)) {
- consentPage.confirm();
- }
- }
- } catch (Exception ignore) {
- // ignore errors when checking consent page, if an error tests will also fail
- }
-
- pause(WAIT_AFTER_OPERATION);
+ public void requestEntitlements(JavascriptStateValidator validator) {
+ testExecutor.executeAsyncScript("var callback = arguments[arguments.length - 1];" +
+ "window.authorization.entitlement('photoz-restful-api').then(function (rpt) {" +
+ " callback(JSON.stringify(jwt_decode(rpt), null, ' '));" +
+ "});", validator);
}
private void waitForDenial() {
@@ -243,28 +177,18 @@ public class PhotozClientAuthzTestApp extends AbstractPageWithInjectedUrl {
pause(WAIT_AFTER_OPERATION);
}
- public void viewAlbum(String name, boolean shouldBeDenied) {
- WebElement viewalbum = driver.findElement(By.xpath("//a[text() = '" + name + "']"));
- waitUntilElement(viewalbum).is().clickable();
- viewalbum.click();
- waitForPageToLoad();
- driver.navigate().refresh(); // This is sometimes necessary for loading the new policy settings
- if (shouldBeDenied) {
- waitForDenial();
- } else {
- waitForNotDenial();
- }
- waitForPageToLoad();
- pause(WAIT_AFTER_OPERATION);
+ public void viewAlbum(String name, ResponseValidator validator) {
+ testExecutor.sendXMLHttpRequest(
+ XMLHttpRequest.create()
+ .method("GET")
+ .addHeader("Accept", "application/json")
+ .url(apiUrl + "/album/" + name + "/")
+ , validator);
}
public void accountPage() {
- navigateTo();
- WebElement myAccount = driver.findElement(By.id("my-account"));
- waitUntilElement(myAccount).is().clickable();
- myAccount.click();
+ testExecutor.openAccountPage(null);
waitForPageToLoad();
- pause(WAIT_AFTER_OPERATION);
}
public void accountMyResources() {
@@ -273,7 +197,6 @@ public class PhotozClientAuthzTestApp extends AbstractPageWithInjectedUrl {
waitUntilElement(myResources).is().clickable();
myResources.click();
waitForPageToLoad();
- pause(WAIT_AFTER_OPERATION);
}
public void accountMyResource(String name) {
@@ -282,7 +205,6 @@ public class PhotozClientAuthzTestApp extends AbstractPageWithInjectedUrl {
waitUntilElement(myResource).is().clickable();
myResource.click();
waitForPageToLoad();
- pause(WAIT_AFTER_OPERATION);
}
public void accountGrantResource(String name, String requester) {
@@ -291,7 +213,6 @@ public class PhotozClientAuthzTestApp extends AbstractPageWithInjectedUrl {
waitUntilElement(grantResource).is().clickable();
grantResource.click();
waitForPageToLoad();
- pause(WAIT_AFTER_OPERATION);
}
public void accountGrantRemoveScope(String name, String requester, String scope) {
@@ -300,7 +221,6 @@ public class PhotozClientAuthzTestApp extends AbstractPageWithInjectedUrl {
waitUntilElement(grantRemoveScope).is().clickable();
grantRemoveScope.click();
waitForPageToLoad();
- pause(WAIT_AFTER_OPERATION);
}
public void accountRevokeResource(String name, String requester) {
@@ -309,7 +229,6 @@ public class PhotozClientAuthzTestApp extends AbstractPageWithInjectedUrl {
waitUntilElement(revokeResource).is().clickable();
revokeResource.click();
waitForPageToLoad();
- pause(WAIT_AFTER_OPERATION);
}
public void accountShareResource(String name, String user) {
@@ -323,7 +242,6 @@ public class PhotozClientAuthzTestApp extends AbstractPageWithInjectedUrl {
waitUntilElement(shareButton).is().clickable();
shareButton.click();
waitForPageToLoad();
- pause(WAIT_AFTER_OPERATION);
}
public void accountShareRemoveScope(String name, String user, String scope) {
@@ -344,7 +262,6 @@ public class PhotozClientAuthzTestApp extends AbstractPageWithInjectedUrl {
shareButton.click();
waitForPageToLoad();
- pause(WAIT_AFTER_OPERATION);
}
public void accountDenyResource(String name) {
@@ -353,25 +270,22 @@ public class PhotozClientAuthzTestApp extends AbstractPageWithInjectedUrl {
waitUntilElement(denyLink).is().clickable();
denyLink.click();
waitForPageToLoad();
- pause(WAIT_AFTER_OPERATION);
}
- public void requestResourceProtectedAnyScope(boolean shouldBeDenied) {
- navigateTo();
- WebElement requestPathWithAnyProtectedScope = driver.findElement(By.id("requestPathWithAnyProtectedScope"));
- waitUntilElement(requestPathWithAnyProtectedScope).is().clickable();
- requestPathWithAnyProtectedScope.click();
- if (shouldBeDenied) waitForDenial();
- pause(WAIT_AFTER_OPERATION);
+ public void requestResourceProtectedAnyScope(ResponseValidator validator) {
+ testExecutor.sendXMLHttpRequest(
+ XMLHttpRequest.create()
+ .method("GET")
+ .url(apiUrl + "/scope-any")
+ , validator);
}
- public void requestResourceProtectedAllScope(boolean shouldBeDenied) {
- navigateTo();
- WebElement requestPathWithAllProtectedScope = driver.findElement(By.id("requestPathWithAllProtectedScope"));
- waitUntilElement(requestPathWithAllProtectedScope).is().clickable();
- requestPathWithAllProtectedScope.click();
- if (shouldBeDenied) waitForDenial();
- pause(WAIT_AFTER_OPERATION);
+ public void requestResourceProtectedAllScope(ResponseValidator validator) {
+ testExecutor.sendXMLHttpRequest(
+ XMLHttpRequest.create()
+ .method("GET")
+ .url(apiUrl + "/scope-all")
+ , validator);
}
public WebElement getOutput() {
@@ -380,8 +294,8 @@ public class PhotozClientAuthzTestApp extends AbstractPageWithInjectedUrl {
@Override
public void navigateTo() {
- super.navigateTo();
- pause(WAIT_AFTER_OPERATION);
+ driver.navigate().to(toString() + "/");
+ waitForPageToLoad();
}
@Override
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/javascript/JavascriptTestExecutorWithAuthorization.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/javascript/JavascriptTestExecutorWithAuthorization.java
new file mode 100644
index 0000000..8ccc554
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/javascript/JavascriptTestExecutorWithAuthorization.java
@@ -0,0 +1,167 @@
+package org.keycloak.testsuite.util.javascript;
+
+import org.keycloak.representations.idm.UserRepresentation;
+import org.keycloak.testsuite.auth.page.login.OAuthGrant;
+import org.keycloak.testsuite.auth.page.login.OIDCLogin;
+import org.keycloak.testsuite.pages.ConsentPage;
+import org.keycloak.testsuite.util.URLUtils;
+import org.openqa.selenium.WebDriver;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.keycloak.testsuite.util.WaitUtils.waitForPageToLoad;
+
+/**
+ * @author mhajas
+ */
+public class JavascriptTestExecutorWithAuthorization extends JavascriptTestExecutor {
+
+ public static JavascriptTestExecutorWithAuthorization create(WebDriver driver, OIDCLogin loginPage) {
+ return new JavascriptTestExecutorWithAuthorization(driver, loginPage);
+ }
+
+ private JavascriptTestExecutorWithAuthorization(WebDriver driver, OIDCLogin loginPage) {
+ super(driver, loginPage);
+ }
+
+
+ @Override
+ public JavascriptTestExecutorWithAuthorization init(JSObjectBuilder argumentsBuilder, JavascriptStateValidator validator) {
+ super.init(argumentsBuilder, validator);
+ Object output = jsExecutor.executeScript(
+ "var callback = arguments[arguments.length - 1];" +
+ "window.authorization = new KeycloakAuthorization(window.keycloak);" +
+ "while (typeof window.authorization === 'undefined') {}" + // Wait until authorization is initialized
+ "return 'Authz initialized'");
+
+ assertThat(output, is("Authz initialized"));
+ return this;
+ }
+
+ @Override
+ public JavascriptTestExecutorWithAuthorization login(JavascriptStateValidator validator) {
+ super.login(validator);
+ return this;
+ }
+
+ public JavascriptTestExecutorWithAuthorization loginFormWithScopesWithPossibleConsentPage(UserRepresentation user, JavascriptStateValidator validator, OAuthGrant oAuthGrantPage, String... scopes) {
+ String currentUrl = jsDriver.getCurrentUrl();
+
+ if (scopes.length > 0) {
+ StringBuilder scopesValue = new StringBuilder();
+
+ for (String scope : scopes) {
+ if (scopesValue.length() != 0) {
+ scopesValue.append(" ");
+ }
+ scopesValue.append(scope);
+ }
+
+ scopesValue.append(" openid");
+
+
+ StringBuilder urlWithScopeParam = new StringBuilder(currentUrl);
+
+ int scopeIndex = currentUrl.indexOf("scope");
+
+ if (scopeIndex != -1) {
+ // Remove scope param from url
+ urlWithScopeParam.delete(scopeIndex, currentUrl.indexOf('&', scopeIndex));
+ // Add scope param to the end of query
+ urlWithScopeParam.append("&").append("scope=");
+ }
+
+ if (!currentUrl.contains("?")) {
+ urlWithScopeParam.append("?scope=");
+ }
+
+ urlWithScopeParam.append(scopesValue);
+
+ URLUtils.navigateToUri(urlWithScopeParam.toString());
+ waitForPageToLoad();
+ }
+
+ loginFormWithPossibleConsentPage(user, oAuthGrantPage, validator);
+ return this;
+ }
+
+ public JavascriptTestExecutorWithAuthorization loginFormWithPossibleConsentPage(UserRepresentation user, OAuthGrant oAuthGrantPage, JavascriptStateValidator validator) {
+ super.loginForm(user);
+
+ try {
+ // simple check if we are at the consent page, if so just click 'Yes'
+ if (oAuthGrantPage.isCurrent(jsDriver)) {
+ oAuthGrantPage.accept();
+ waitForPageToLoad();
+ }
+ } catch (Exception ignore) {
+ // ignore errors when checking consent page, if an error tests will also fail
+ }
+
+ if (validator != null) {
+ validator.validate(jsDriver, null, events);
+ }
+
+ return this;
+ }
+
+ @Override
+ public JavascriptTestExecutor sendXMLHttpRequest(XMLHttpRequest request, ResponseValidator validator) {
+ // Intercept all requests and add rpt or token
+
+ // check if rpt is already present
+ Object o = jsExecutor.executeScript("if(window.authorization && window.authorization.rpt) return true; else return false;");
+
+
+
+ if (o == null || o.equals(false)) {
+ // RPT is not present yet, lets try to use bearer token
+ request.includeBearerToken();
+ } else {
+ // RPT token is present so we will use it
+ request.includeRpt();
+ }
+
+ // Try to send request
+ Map<String, Object> result = request.send(jsExecutor);
+
+ // If request was denied do UMA
+ if ((Long.valueOf(403).equals(result.get("status")) || Long.valueOf(401).equals(result.get("status")))) {
+ //extracting ticket from response
+ String headersString = (String) result.get("responseHeaders");
+
+ List<String> headersList = Arrays.asList(headersString.split("\r\n"));
+ String wwwAuthenticate = headersList.stream().filter(s -> s.toLowerCase().startsWith("www-authenticate:")).findFirst().get();
+
+ if (wwwAuthenticate.contains("UMA") && wwwAuthenticate.contains("ticket")) {
+ String ticket = Arrays.asList(wwwAuthenticate.split(",")).stream().filter(s -> s.startsWith("ticket")).findFirst().get();
+
+ ticket = ticket.substring(0, ticket.length() - 1).replaceFirst("ticket=\"", "");
+
+ // AuthorizationRequest for RPT
+ o = jsExecutor.executeAsyncScript(
+ "var callback = arguments[arguments.length - 1];" +
+ "window.authorization" +
+ ".authorize(" + JSObjectBuilder.create().add("ticket", ticket).build() + ")" +
+ ".then(function (rpt) {callback(rpt)}, function() {callback('failed1')}, function() {callback('failed2')});");
+
+ o = jsExecutor.executeScript("if(window.authorization && window.authorization.rpt) return true; else return false;"); // return window.authorization && window.authorization.rpt doesn't work
+
+ if (o != null && o.equals(true)) {
+ request.includeRpt();
+ result = request.send(jsExecutor);
+ }
+ }
+ }
+
+ if (validator != null) {
+ validator.validate(result);
+ }
+
+ return this;
+ }
+}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractPhotozExampleAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractPhotozExampleAdapterTest.java
index 344d68e..a1edd7f 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractPhotozExampleAdapterTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractPhotozExampleAdapterTest.java
@@ -20,25 +20,19 @@ import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.LaxRedirectStrategy;
+import org.hamcrest.CoreMatchers;
import org.jboss.arquillian.container.test.api.Deployer;
-import org.jboss.arquillian.drone.api.annotation.Drone;
import org.jboss.arquillian.graphene.page.Page;
import org.jboss.arquillian.test.api.ArquillianResource;
-import org.jboss.shrinkwrap.api.asset.StringAsset;
-import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Ignore;
import org.junit.Test;
import org.keycloak.admin.client.resource.AuthorizationResource;
import org.keycloak.admin.client.resource.ClientResource;
import org.keycloak.admin.client.resource.ClientScopesResource;
import org.keycloak.admin.client.resource.ClientsResource;
-import org.keycloak.admin.client.resource.ProtocolMappersResource;
import org.keycloak.admin.client.resource.RealmResource;
-import org.keycloak.admin.client.resource.RealmsResource;
import org.keycloak.admin.client.resource.ResourcesResource;
import org.keycloak.admin.client.resource.RoleResource;
import org.keycloak.admin.client.resource.UserResource;
@@ -54,84 +48,89 @@ import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.representations.idm.authorization.PolicyRepresentation;
import org.keycloak.representations.idm.authorization.ResourceRepresentation;
import org.keycloak.representations.idm.authorization.ResourceServerRepresentation;
-import org.keycloak.testsuite.ProfileAssume;
-import org.keycloak.testsuite.adapter.AbstractExampleAdapterTest;
import org.keycloak.testsuite.adapter.page.PhotozClientAuthzTestApp;
import org.keycloak.testsuite.admin.ApiUtil;
-import org.keycloak.testsuite.auth.page.login.OIDCLogin;
+import org.keycloak.testsuite.arquillian.AppServerTestEnricher;
+import org.keycloak.testsuite.auth.page.login.OAuthGrant;
import org.keycloak.testsuite.util.ContainerAssume;
import org.keycloak.testsuite.util.DroneUtils;
import org.keycloak.testsuite.util.JavascriptBrowser;
-import org.keycloak.testsuite.utils.io.IOUtil;
+import org.keycloak.testsuite.util.javascript.JavascriptTestExecutorWithAuthorization;
import org.keycloak.util.JsonSerialization;
-import org.openqa.selenium.By;
-import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
-import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
-import static org.hamcrest.Matchers.empty;
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.not;
+import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
-import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWithLoginUrlOf;
+import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWith;
import static org.keycloak.testsuite.utils.io.IOUtil.loadJson;
import static org.keycloak.testsuite.utils.io.IOUtil.loadRealm;
import static org.keycloak.testsuite.util.WaitUtils.waitForPageToLoad;
-import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
import javax.ws.rs.core.Response;
-import org.keycloak.testsuite.arquillian.AppServerTestEnricher;
/**
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
*/
-public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAdapterTest {
+public abstract class AbstractPhotozExampleAdapterTest extends AbstractPhotozJavascriptExecutorTest {
- private static final String REALM_NAME = "photoz";
protected static final String RESOURCE_SERVER_ID = "photoz-restful-api";
+ protected static final String ALICE_ALBUM_NAME = "Alice-Family-Album";
private static final int TOKEN_LIFESPAN_LEEWAY = 3; // seconds
@ArquillianResource
private Deployer deployer;
- // Javascript browser needed KEYCLOAK-4703
- @Drone
+ @Page
@JavascriptBrowser
- protected WebDriver jsDriver;
+ private PhotozClientAuthzTestApp clientPage;
@Page
@JavascriptBrowser
- protected OIDCLogin jsDriverTestRealmLoginPage;
+ private OAuthGrant oAuthGrantPage;
- @Page
+ private JavascriptTestExecutorWithAuthorization testExecutor;
+
+ @FindBy(id = "output")
@JavascriptBrowser
- private PhotozClientAuthzTestApp clientPage;
+ protected WebElement outputArea;
+
+ @FindBy(id = "events")
+ @JavascriptBrowser
+ protected WebElement eventsArea;
@Override
public void setDefaultPageUriParameters() {
super.setDefaultPageUriParameters();
testRealmPage.setAuthRealm(REALM_NAME);
+ oAuthGrantPage.setAuthRealm(REALM_NAME);
}
@Before
public void beforePhotozExampleAdapterTest() throws Exception {
DroneUtils.addWebDriver(jsDriver);
- deleteAllCookiesForClientPage();
this.deployer.deploy(RESOURCE_SERVER_ID);
-
+
+ clientPage.navigateTo();
+ waitForPageToLoad();
+ assertCurrentUrlStartsWith(clientPage.toString());
+
+ testExecutor = JavascriptTestExecutorWithAuthorization.create(jsDriver, jsDriverTestRealmLoginPage);
+ clientPage.setTestExecutorPlayground(testExecutor, appServerContextRootPage + "/" + RESOURCE_SERVER_ID);
+ jsDriver.manage().deleteAllCookies();
+
try (CloseableHttpClient httpClient = HttpClientBuilder.create().setRedirectStrategy(new LaxRedirectStrategy()).build()) {
HttpGet request = new HttpGet(clientPage.toString() + "/unsecured/clean");
httpClient.execute(request).close();
@@ -159,18 +158,6 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd
importResourceServerSettings();
}
- //revert provider in persistence.xml for EAP6 backward compatibility
- protected static void updatePersistenceXml(WebArchive war) {
- //double check app server is eap6
- if (AppServerTestEnricher.isEAP6AppServer()) {
- String persistanceXmlPath = "/WEB-INF/classes/META-INF/persistence.xml";
- org.w3c.dom.Document persistenceXml = IOUtil.loadXML(war.get(persistanceXmlPath).getAsset().openStream());
- IOUtil.modifyDocElementValue(persistenceXml, "provider",
- "org.hibernate.jpa.HibernatePersistenceProvider", "org.hibernate.ejb.HibernatePersistence");
- war.add(new StringAsset((IOUtil.documentToString(persistenceXml))), persistanceXmlPath);
- }
- }
-
private List<ResourceRepresentation> getResourcesOfUser(String username) throws FileNotFoundException {
return getAuthorizationResource().resources().resources().stream().filter(resource -> resource.getOwner().getName().equals(username)).collect(Collectors.toList());
}
@@ -178,50 +165,62 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd
private void printUpdatedPolicies() throws FileNotFoundException {
log.debug("Check updated policies");
for (PolicyRepresentation policy : getAuthorizationResource().policies().policies()) {
- log.debugf("Policy: {0}", policy.getName());
+ log.debugf("Policy: %s", policy.getName());
for (String key : policy.getConfig().keySet()) {
- log.debugf("-- key: {0}, value: {1}", key, policy.getConfig().get(key));
+ log.debugf("-- key: %s, value: %s", key, policy.getConfig().get(key));
}
}
log.debug("------------------------------");
}
+
+ private void assertOnTestAppUrl(WebDriver jsDriver, Object output, WebElement events) {
+ waitForPageToLoad();
+ assertCurrentUrlStartsWith(clientPage.toString(), jsDriver);
+ }
+
+ private void assertWasDenied(Map<String, Object> response) {
+ assertThat(response.get("status")).isEqualTo(401L);
+ }
+
+ private void assertWasNotDenied(Map<String, Object> response) {
+ assertThat(response.get("status")).isEqualTo(200L);
+ }
@Test
public void testUserCanCreateAndDeleteAlbum() throws Exception {
- loginToClientPage("alice", "alice");
+ loginToClientPage(aliceUser);
- clientPage.createAlbum("Alice Family Album");
+ clientPage.createAlbum(ALICE_ALBUM_NAME);
log.debug("Check if alice has resources stored");
- assertThat(getResourcesOfUser("alice"), is(not(empty())));
+ assertThat(getResourcesOfUser("alice")).isNotEmpty();
- clientPage.deleteAlbum("Alice Family Album", false);
+ clientPage.deleteAlbum(ALICE_ALBUM_NAME, this::assertWasNotDenied);
log.debug("Check if alice has resources deleted");
- assertThat(getResourcesOfUser("alice"), is(empty()));
+ assertThat(getResourcesOfUser("alice")).isEmpty();
}
@Test
public void createAlbumWithInvalidUser() throws Exception {
- loginToClientPage("alice", "alice");
-
- clientPage.createAlbumWithInvalidUser("Alice Family Album");
+ loginToClientPage(aliceUser);
- log.debug("Check if the album was not created.");
- waitUntilElement(clientPage.getOutput()).text().not().contains("Request was successful");
- waitUntilElement(clientPage.getOutput()).text().contains("Could not register protected resource");
+ clientPage.createAlbumWithInvalidUser(ALICE_ALBUM_NAME, response -> {
+ assertThat(response.get("status")).isEqualTo(500L);
+ assertThat(response.get("res")).isEqualTo("Could not register protected resource.");
+ });
}
@Test
public void testOnlyOwnerCanDeleteAlbum() throws Exception {
- ContainerAssume.assumeNotAuthServerUndertow();
+ ContainerAssume.assumeNotAppServerUndertow();
- loginToClientPage("alice", "alice");
- clientPage.createAlbum("Alice-Family-Album");
+ loginToClientPage(aliceUser);
+ clientPage.createAlbum(ALICE_ALBUM_NAME);
- loginToClientPage("admin", "admin");
- clientPage.navigateToAdminAlbum(false);
+ loginToClientPage(adminUser);
+ clientPage.navigateToAdminAlbum(this::assertWasNotDenied);
log.debug("Check if alice has resources stored");
- assertThat(getResourcesOfUser("alice"), is(not(empty())));
+ assertThat(getResourcesOfUser("alice")).isNotEmpty();
log.debug("Adding applyPolicies \"Only Owner Policy\" to \"Delete Album Permission\" policies.");
for (PolicyRepresentation policy : getAuthorizationResource().policies().policies()) {
@@ -232,13 +231,13 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd
}
printUpdatedPolicies();
- loginToClientPage("admin", "admin");
+ loginToClientPage(adminUser);
- clientPage.navigateToAdminAlbum(false);
- clientPage.deleteAlbum("Alice-Family-Album", true);
+ clientPage.navigateToAdminAlbum(this::assertWasNotDenied);
+ clientPage.deleteAlbum(ALICE_ALBUM_NAME, this::assertWasDenied);
log.debug("Check if alice has resources stored");
- assertThat(getResourcesOfUser("alice"), is(not(empty())));
+ assertThat(getResourcesOfUser("alice")).isNotEmpty();
log.debug("Adding applyPolicies \"Only Owner and Administrators Policy\" to \"Delete Album Permission\" policies.");
for (PolicyRepresentation policy : getAuthorizationResource().policies().policies()) {
@@ -249,51 +248,52 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd
}
printUpdatedPolicies();
- clientPage.navigateToAdminAlbum(false);
- clientPage.deleteAlbum("Alice-Family-Album", false);
+ clientPage.navigateToAdminAlbum(this::assertWasNotDenied);
+ clientPage.deleteAlbum(ALICE_ALBUM_NAME, this::assertWasNotDenied);
log.debug("Check if alice has resources deleted");
- assertThat(getResourcesOfUser("alice"), is(empty()));
+ assertThat(getResourcesOfUser("alice")).isEmpty();
}
@Test
public void testRegularUserCanNotAccessAdminResources() throws Exception {
- loginToClientPage("alice", "alice");
- clientPage.navigateToAdminAlbum(true);
+ loginToClientPage(aliceUser);
+ clientPage.navigateToAdminAlbum(this::assertWasDenied);
}
@Test
public void testAdminOnlyFromSpecificAddress() throws Exception {
- ContainerAssume.assumeNotAuthServerUndertow();
-
- loginToClientPage("admin", "admin");
- clientPage.navigateToAdminAlbum(false);
+ loginToClientPage(adminUser);
+ clientPage.navigateToAdminAlbum(this::assertWasNotDenied);
log.debug("Changing codes \"127.0.0.1\" to \"127.3.3.3\" of \"Only From a Specific Client Address\" policies.");
for (PolicyRepresentation policy : getAuthorizationResource().policies().policies()) {
if ("Only From a Specific Client Address".equals(policy.getName())) {
- String code = policy.getConfig().get("code");
- policy.getConfig().put("code", code.replaceAll("127.0.0.1", "127.3.3.3"));
+ String code = policy.getConfig().get("code")
+ .replaceAll("127.0.0.1", "127.3.3.3")
+ .replaceAll("0:0:0:0:0:0:0:1", "0:0:0:0:0:ffff:7f03:303");
+ policy.getConfig().put("code", code);
getAuthorizationResource().policies().policy(policy.getId()).update(policy);
}
}
printUpdatedPolicies();
- clientPage.navigateToAdminAlbum(true);
+ loginToClientPage(adminUser);
+ clientPage.navigateToAdminAlbum(this::assertWasDenied);
}
@Test
public void testAdminWithoutPermissionsToTypedResource() throws Exception {
- ContainerAssume.assumeNotAuthServerUndertow();
+ ContainerAssume.assumeNotAppServerUndertow();
- loginToClientPage("alice", "alice");
- clientPage.createAlbum("Alice Family Album");
+ loginToClientPage(aliceUser);
+ clientPage.createAlbum(ALICE_ALBUM_NAME);
- loginToClientPage("admin", "admin");
- clientPage.navigateToAdminAlbum(false);
+ loginToClientPage(adminUser);
+ clientPage.navigateToAdminAlbum(this::assertWasNotDenied);
- clientPage.viewAlbum("Alice Family Album", false);
+ clientPage.viewAlbum(ALICE_ALBUM_NAME, this::assertWasNotDenied);
for (PolicyRepresentation policy : getAuthorizationResource().policies().policies()) {
if ("Album Resource Permission".equals(policy.getName())) {
@@ -315,11 +315,13 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd
}
printUpdatedPolicies();
- clientPage.navigateToAdminAlbum(false);
+ loginToClientPage(adminUser); // Clear cache
+
+ clientPage.navigateToAdminAlbum(this::assertWasNotDenied);
- clientPage.viewAlbum("Alice Family Album", true);
- clientPage.navigateToAdminAlbum(false);
- clientPage.deleteAlbum("Alice Family Album", true);
+ clientPage.viewAlbum(ALICE_ALBUM_NAME, this::assertWasDenied);
+ clientPage.navigateToAdminAlbum(this::assertWasNotDenied);
+ clientPage.deleteAlbum(ALICE_ALBUM_NAME, this::assertWasDenied);
for (PolicyRepresentation policy : getAuthorizationResource().policies().policies()) {
if ("Album Resource Permission".equals(policy.getName())) {
@@ -329,26 +331,27 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd
}
printUpdatedPolicies();
- clientPage.navigateToAdminAlbum(false);
- clientPage.viewAlbum("Alice Family Album", false);
+ loginToClientPage(adminUser); // Clear cache
- clientPage.navigateToAdminAlbum(false);
- clientPage.deleteAlbum("Alice Family Album", false);
- assertThat(getResourcesOfUser("alice"), is(empty()));
+ clientPage.navigateToAdminAlbum(this::assertWasNotDenied);
+ clientPage.viewAlbum(ALICE_ALBUM_NAME, this::assertWasNotDenied);
+
+ clientPage.navigateToAdminAlbum(this::assertWasNotDenied);
+ clientPage.deleteAlbum(ALICE_ALBUM_NAME, this::assertWasNotDenied);
+ assertThat(getResourcesOfUser("alice")).isEmpty();
}
@Test
public void testAdminWithoutPermissionsToDeleteAlbum() throws Exception {
- ContainerAssume.assumeNotAuthServerUndertow();
-
- loginToClientPage("alice", "alice");
- clientPage.createAlbum("Alice Family Album");
+ loginToClientPage(aliceUser);
+ clientPage.createAlbum(ALICE_ALBUM_NAME);
- loginToClientPage("admin", "admin");
- clientPage.navigateToAdminAlbum(false);
+ loginToClientPage(adminUser);
+ clientPage.navigateToAdminAlbum(this::assertWasNotDenied);
+ clientPage.viewAlbum(ALICE_ALBUM_NAME, this::assertWasNotDenied);
- clientPage.deleteAlbum("Alice Family Album", false);
- assertThat(getResourcesOfUser("alice"), is(empty()));
+ clientPage.deleteAlbum(ALICE_ALBUM_NAME, this::assertWasNotDenied);
+ assertThat(getResourcesOfUser("alice")).isEmpty();
for (PolicyRepresentation policy : getAuthorizationResource().policies().policies()) {
if ("Delete Album Permission".equals(policy.getName())) {
@@ -358,16 +361,16 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd
}
printUpdatedPolicies();
- loginToClientPage("alice", "alice");
- clientPage.createAlbum("Alice Family Album");
+ loginToClientPage(aliceUser);
+ clientPage.createAlbum(ALICE_ALBUM_NAME);
- loginToClientPage("admin", "admin");
- clientPage.navigateToAdminAlbum(false);
- clientPage.viewAlbum("Alice Family Album", false);
- assertThat(getResourcesOfUser("alice"), is(not(empty())));
+ loginToClientPage(adminUser);
+ clientPage.navigateToAdminAlbum(this::assertWasNotDenied);
+ clientPage.viewAlbum(ALICE_ALBUM_NAME, this::assertWasNotDenied);
+ assertThat(getResourcesOfUser("alice")).isNotEmpty();
- clientPage.navigateToAdminAlbum(false);
- clientPage.deleteAlbum("Alice Family Album", true);
+ clientPage.navigateToAdminAlbum(this::assertWasNotDenied);
+ clientPage.deleteAlbum(ALICE_ALBUM_NAME, this::assertWasDenied);
for (PolicyRepresentation policy : getAuthorizationResource().policies().policies()) {
if ("Delete Album Permission".equals(policy.getName())) {
@@ -377,18 +380,18 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd
}
printUpdatedPolicies();
- clientPage.navigateToAdminAlbum(false);
- clientPage.deleteAlbum("Alice Family Album", false);
- assertThat(getResourcesOfUser("alice"), is(empty()));
+ loginToClientPage(adminUser); // Clear cache
+
+ clientPage.navigateToAdminAlbum(this::assertWasNotDenied);
+ clientPage.deleteAlbum(ALICE_ALBUM_NAME, this::assertWasNotDenied);
+ assertThat(getResourcesOfUser("alice")).isEmpty();
}
@Test
public void testClientRoleRepresentingUserConsent() throws Exception {
- ContainerAssume.assumeNotAuthServerUndertow();
-
- loginToClientPage("alice", "alice");
- clientPage.createAlbum("Alice Family Album");
- clientPage.viewAlbum("Alice Family Album", false);
+ loginToClientPage(aliceUser);
+ clientPage.createAlbum(ALICE_ALBUM_NAME);
+ clientPage.viewAlbum(ALICE_ALBUM_NAME, this::assertWasNotDenied);
RealmResource realmResource = realmsResouce().realm(REALM_NAME);
UsersResource usersResource = realmResource.users();
@@ -406,19 +409,19 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd
setManageAlbumScopeRequired();
- loginToClientPage("alice", "alice");
- clientPage.viewAlbum("Alice Family Album", true);
+ loginToClientPage(aliceUser);
+ clientPage.viewAlbum(ALICE_ALBUM_NAME, this::assertWasDenied);
- loginToClientPage("alice", "alice", "manage-albums");
- clientPage.viewAlbum("Alice Family Album", false);
+ loginToClientPage(aliceUser, "manage-albums");
+ clientPage.viewAlbum(ALICE_ALBUM_NAME, this::assertWasNotDenied);
}
@Test
public void testClientRoleNotRequired() throws Exception {
- loginToClientPage("alice", "alice");
+ loginToClientPage(aliceUser);
- clientPage.createAlbum("Alice Family Album");
- clientPage.viewAlbum("Alice Family Album", false);
+ clientPage.createAlbum(ALICE_ALBUM_NAME);
+ clientPage.viewAlbum(ALICE_ALBUM_NAME, this::assertWasNotDenied);
UsersResource usersResource = realmsResouce().realm(REALM_NAME).users();
List<UserRepresentation> users = usersResource.search("alice", null, null, null, null, null);
@@ -440,8 +443,8 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd
manageAlbumRole.update(roleRepresentation);
- loginToClientPage("alice", "alice");
- clientPage.viewAlbum("Alice Family Album", true);
+ loginToClientPage(aliceUser);
+ clientPage.viewAlbum(ALICE_ALBUM_NAME, this::assertWasDenied);
for (PolicyRepresentation policy : getAuthorizationResource().policies().policies()) {
if ("Any User Policy".equals(policy.getName())) {
@@ -460,34 +463,28 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd
}
printUpdatedPolicies();
- loginToClientPage("alice", "alice");
- clientPage.viewAlbum("Alice Family Album", false);
+ loginToClientPage(aliceUser);
+ clientPage.viewAlbum(ALICE_ALBUM_NAME, this::assertWasNotDenied);
}
@Test
public void testOverridePermissionFromResourceParent() throws Exception {
- ContainerAssume.assumeNotAuthServerUndertow();
-
- loginToClientPage("alice", "alice");
- String resourceName = "My Resource Instance";
+ loginToClientPage(aliceUser);
+ String resourceName = "My-Resource-Instance";
clientPage.createAlbum(resourceName);
- clientPage.viewAlbum(resourceName, false);
-
- clientPage.navigateTo();
- clientPage.deleteAlbum(resourceName, false);
+ clientPage.viewAlbum(resourceName, this::assertWasNotDenied);
+ clientPage.deleteAlbum(resourceName, this::assertWasNotDenied);
clientPage.createAlbum(resourceName);
- loginToClientPage("admin", "admin");
+ loginToClientPage(adminUser);
- clientPage.navigateToAdminAlbum(false);
- clientPage.viewAlbum(resourceName, false);
+ clientPage.navigateToAdminAlbum(this::assertWasNotDenied);
+ clientPage.viewAlbum(resourceName, this::assertWasNotDenied);
+ clientPage.deleteAlbum(resourceName, this::assertWasNotDenied);
- clientPage.navigateToAdminAlbum(false);
- clientPage.deleteAlbum(resourceName, false);
-
- loginToClientPage("alice", "alice");
+ loginToClientPage(aliceUser);
clientPage.createAlbum(resourceName);
getAuthorizationResource().resources().resources().forEach(resource -> {
@@ -512,54 +509,45 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd
});
printUpdatedPolicies();
- loginToClientPage("admin", "admin");
-
- clientPage.navigateToAdminAlbum(false);
- clientPage.viewAlbum(resourceName, true);
-
- clientPage.navigateToAdminAlbum(false);
- clientPage.deleteAlbum(resourceName, true);
+ loginToClientPage(adminUser);
- loginToClientPage("alice", "alice");
- clientPage.deleteAlbum(resourceName, false);
+ clientPage.navigateToAdminAlbum(this::assertWasNotDenied);
+ clientPage.viewAlbum(resourceName, this::assertWasDenied);
+ clientPage.deleteAlbum(resourceName, this::assertWasDenied);
- assertThat(getResourcesOfUser("alice"), is(empty()));
+ loginToClientPage(aliceUser);
+ clientPage.deleteAlbum(resourceName, this::assertWasNotDenied);
+ assertThat(getResourcesOfUser("alice")).isEmpty();
}
@Test
public void testInheritPermissionFromResourceParent() throws Exception {
- ContainerAssume.assumeNotAuthServerUndertow();
+ ContainerAssume.assumeNotAppServerUndertow();
- loginToClientPage("alice", "alice");
+ loginToClientPage(aliceUser);
- String resourceName = "My Resource Instance";
- clientPage.createAlbum(resourceName);
+ final String RESOURCE_NAME = "My-Resource-Instance";
+ clientPage.createAlbum(RESOURCE_NAME);
+ clientPage.viewAlbum(RESOURCE_NAME, this::assertWasNotDenied);
+ clientPage.deleteAlbum(RESOURCE_NAME, this::assertWasNotDenied);
- clientPage.viewAlbum(resourceName, false);
+ clientPage.createAlbum(RESOURCE_NAME);
- clientPage.navigateTo();
- clientPage.deleteAlbum(resourceName, false);
+ loginToClientPage(adminUser);
+ clientPage.navigateToAdminAlbum(this::assertWasNotDenied);
+ clientPage.viewAlbum(RESOURCE_NAME, this::assertWasNotDenied);
+ clientPage.deleteAlbum(RESOURCE_NAME, this::assertWasNotDenied);
- clientPage.createAlbum(resourceName);
-
- loginToClientPage("admin", "admin");
-
- clientPage.navigateToAdminAlbum(false);
- clientPage.viewAlbum(resourceName, false);
-
- clientPage.navigateToAdminAlbum(false);
- clientPage.deleteAlbum(resourceName, false);
-
- loginToClientPage("alice", "alice");
- clientPage.createAlbum(resourceName);
+ loginToClientPage(aliceUser);
+ clientPage.createAlbum(RESOURCE_NAME);
ResourcesResource resourcesResource = getAuthorizationResource().resources();
resourcesResource.resources().forEach(resource -> {
- if (resource.getName().equals(resourceName)) {
+ if (resource.getName().equals(RESOURCE_NAME)) {
try {
PolicyRepresentation resourceInstancePermission = new PolicyRepresentation();
- resourceInstancePermission.setName(resourceName + "Permission");
+ resourceInstancePermission.setName(RESOURCE_NAME + "Permission");
resourceInstancePermission.setType("resource");
Map<String, String> config = new HashMap<>();
@@ -575,140 +563,151 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd
}
});
- loginToClientPage("admin", "admin");
-
- clientPage.navigateToAdminAlbum(false);
- clientPage.viewAlbum(resourceName, true);
+ loginToClientPage(adminUser);
- clientPage.navigateToAdminAlbum(false);
- clientPage.deleteAlbum(resourceName, true);
+ clientPage.navigateToAdminAlbum(this::assertWasNotDenied);
+ clientPage.viewAlbum(RESOURCE_NAME, this::assertWasDenied);
+ clientPage.deleteAlbum(RESOURCE_NAME, this::assertWasDenied);
resourcesResource.resources().forEach(resource -> {
- if (resource.getName().equals(resourceName)) {
+ if (resource.getName().equals(RESOURCE_NAME)) {
resource.setScopes(resource.getScopes().stream().filter(scope -> !scope.getName().equals("album:view")).collect(Collectors.toSet()));
resourcesResource.resource(resource.getId()).update(resource);
}
});
- loginToClientPage("admin", "admin");
-
- clientPage.navigateToAdminAlbum(false);
- clientPage.viewAlbum(resourceName, false);
+ loginToClientPage(adminUser);
- clientPage.navigateToAdminAlbum(false);
- clientPage.deleteAlbum(resourceName, true);
+ clientPage.navigateToAdminAlbum(this::assertWasNotDenied);
+ clientPage.viewAlbum(RESOURCE_NAME, this::assertWasNotDenied);
+ clientPage.deleteAlbum(RESOURCE_NAME, this::assertWasDenied);
- loginToClientPage("alice", "alice");
- clientPage.deleteAlbum(resourceName, false);
+ loginToClientPage(aliceUser);
+ clientPage.deleteAlbum(RESOURCE_NAME, this::assertWasNotDenied);
List<ResourceRepresentation> resources = resourcesResource.resources();
assertTrue(resources.stream().filter(resource -> resource.getOwner().getName().equals("alice")).collect(Collectors.toList()).isEmpty());
-
- resourcesResource.resources().forEach(resource -> {
- if (resource.getName().equals(resourceName)) {
- resource.setScopes(Collections.emptySet());
- resourcesResource.resource(resource.getId()).update(resource);
- }
- });
}
//KEYCLOAK-3777
@Test
public void testEntitlementRequest() throws Exception {
- ContainerAssume.assumeNotAuthServerUndertow();
-
- clientPage.navigateTo();
- loginToClientPage("admin", "admin");
+ loginToClientPage(adminUser);
- clientPage.requestEntitlements();
- assertTrue(jsDriver.getPageSource().contains("admin:manage"));
+ clientPage.requestEntitlements((driver1, output, events) -> assertThat((String)output).contains("admin:manage"));
- clientPage.requestEntitlement();
- String pageSource = jsDriver.getPageSource();
- assertTrue(pageSource.contains("album:view"));
- assertTrue(pageSource.contains("album:delete"));
+ loginToClientPage(adminUser);
+ clientPage.requestEntitlement((driver1, output, events) -> assertThat((String)output)
+ .doesNotContain("admin:manage")
+ .contains("album:view")
+ .contains("album:delete")
+ );
}
+
@Test
public void testResourceProtectedWithAnyScope() throws Exception {
- loginToClientPage("alice", "alice");
- clientPage.requestResourceProtectedAllScope(true);
- clientPage.requestResourceProtectedAnyScope(false);
+ loginToClientPage(aliceUser);
+
+ clientPage.requestResourceProtectedAllScope(this::assertWasDenied);
+ clientPage.requestResourceProtectedAnyScope(response -> {
+ assertThat(response.get("status")).isIn(404L, 0L); // PhantomJS returns 0 and chrome 404
+ });
}
+
@Test
public void testRequestResourceToOwner() throws Exception {
- loginToClientPage("alice", "alice");
- clientPage.createAlbum("Alice-Family-Album", true);
+ loginToClientPage(aliceUser);
+ clientPage.createAlbum(ALICE_ALBUM_NAME, true);
- loginToClientPage("jdoe", "jdoe");
- clientPage.viewAllAlbums();
- clientPage.viewAlbum("Alice-Family-Album", true);
- clientPage.navigateTo();
- clientPage.viewAllAlbums();
- clientPage.deleteAlbum("Alice-Family-Album", true);
+ loginToClientPage(jdoeUser);
+ clientPage.viewAlbum(ALICE_ALBUM_NAME, this::assertWasDenied);
+ clientPage.deleteAlbum(ALICE_ALBUM_NAME, this::assertWasDenied);
- loginToClientPage("alice", "alice");
- clientPage.accountGrantResource("Alice-Family-Album", "jdoe");
+ loginToClientPage(aliceUser);
+ clientPage.accountGrantResource(ALICE_ALBUM_NAME, "jdoe");
- loginToClientPage("jdoe", "jdoe");
- clientPage.viewAllAlbums();
- clientPage.viewAlbum("Alice-Family-Album", false);
+ // get back to clientPage and init javascript adapter in order to log out correctly
clientPage.navigateTo();
- clientPage.viewAllAlbums();
- clientPage.deleteAlbum("Alice-Family-Album", false);
- loginToClientPage("alice", "alice");
- clientPage.createAlbum("Alice-Family-Album", true);
+ testExecutor.init(defaultArguments(), this::assertInitNotAuth)
+ .login()
+ .init(defaultArguments(), this::assertSuccessfullyLoggedIn);
- loginToClientPage("jdoe", "jdoe");
- clientPage.viewAllAlbums();
- clientPage.viewAlbum("Alice-Family-Album", true);
- clientPage.navigateTo();
- clientPage.viewAllAlbums();
- clientPage.deleteAlbum("Alice-Family-Album", true);
+ loginToClientPage(jdoeUser);
+ clientPage.viewAlbum(ALICE_ALBUM_NAME, this::assertWasNotDenied);
+ clientPage.deleteAlbum(ALICE_ALBUM_NAME, this::assertWasNotDenied);
+
+ loginToClientPage(aliceUser);
+ clientPage.createAlbum(ALICE_ALBUM_NAME, true);
- loginToClientPage("alice", "alice");
- clientPage.accountGrantRemoveScope("Alice-Family-Album", "jdoe", "album:delete");
- clientPage.accountGrantResource("Alice-Family-Album", "jdoe");
+ loginToClientPage(jdoeUser);
+ clientPage.viewAlbum(ALICE_ALBUM_NAME, this::assertWasDenied);
+ clientPage.deleteAlbum(ALICE_ALBUM_NAME, this::assertWasDenied);
- loginToClientPage("jdoe", "jdoe");
- clientPage.viewAllAlbums();
- clientPage.viewAlbum("Alice-Family-Album", false);
+ loginToClientPage(aliceUser);
+ clientPage.accountGrantRemoveScope(ALICE_ALBUM_NAME, "jdoe", "album:delete");
+
+ // get back to clientPage and init javascript adapter in order to navigate to accountPage again
+ clientPage.navigateTo();
+ testExecutor.init(defaultArguments(), this::assertInitNotAuth)
+ .login(this::assertOnTestAppUrl)
+ .init(defaultArguments(), this::assertSuccessfullyLoggedIn);
+ clientPage.accountGrantResource(ALICE_ALBUM_NAME, "jdoe");
+
+ // get back to clientPage and init javascript adapter in order to log out correctly
clientPage.navigateTo();
- clientPage.viewAllAlbums();
- clientPage.deleteAlbum("Alice-Family-Album", true);
+ testExecutor.init(defaultArguments(), this::assertInitNotAuth)
+ .login()
+ .init(defaultArguments(), this::assertSuccessfullyLoggedIn);
+
+
+ loginToClientPage(jdoeUser);
+ clientPage.viewAlbum(ALICE_ALBUM_NAME, this::assertWasNotDenied);
+ clientPage.deleteAlbum(ALICE_ALBUM_NAME, this::assertWasDenied);
}
@Test
public void testOwnerSharingResource() throws Exception {
- loginToClientPage("alice", "alice");
- clientPage.createAlbum("Alice-Family-Album", true);
- clientPage.accountShareResource("Alice-Family-Album", "jdoe");
+ loginToClientPage(aliceUser);
+ clientPage.createAlbum(ALICE_ALBUM_NAME, true);
+ clientPage.accountShareResource(ALICE_ALBUM_NAME, "jdoe");
- loginToClientPage("jdoe", "jdoe");
- clientPage.viewAllAlbums();
- clientPage.viewAlbum("Alice-Family-Album", false);
+ // get back to clientPage and init javascript adapter in order to log out correctly
clientPage.navigateTo();
- clientPage.viewAllAlbums();
- clientPage.deleteAlbum("Alice-Family-Album", false);
+ testExecutor.init(defaultArguments(), this::assertInitNotAuth)
+ .login()
+ .init(defaultArguments(), this::assertSuccessfullyLoggedIn);
- loginToClientPage("alice", "alice");
- clientPage.createAlbum("Alice-Family-Album", true);
- clientPage.accountShareRemoveScope("Alice-Family-Album", "jdoe", "album:delete");
+ loginToClientPage(jdoeUser);
+ clientPage.viewAlbum(ALICE_ALBUM_NAME, this::assertWasNotDenied);
+ clientPage.deleteAlbum(ALICE_ALBUM_NAME, this::assertWasNotDenied);
- loginToClientPage("jdoe", "jdoe");
- clientPage.viewAllAlbums();
- clientPage.viewAlbum("Alice-Family-Album", false);
+ loginToClientPage(aliceUser);
+ clientPage.createAlbum(ALICE_ALBUM_NAME, true);
+ clientPage.accountShareRemoveScope(ALICE_ALBUM_NAME, "jdoe", "album:delete");
+
+ // get back to clientPage and init javascript adapter in order to log out correctly
clientPage.navigateTo();
- clientPage.viewAllAlbums();
- clientPage.deleteAlbum("Alice-Family-Album", true);
+ testExecutor.init(defaultArguments(), this::assertInitNotAuth)
+ .login(this::assertOnTestAppUrl)
+ .init(defaultArguments(), this::assertSuccessfullyLoggedIn);
+
+ loginToClientPage(jdoeUser);
+ clientPage.viewAlbum(ALICE_ALBUM_NAME, this::assertWasNotDenied);
+ clientPage.deleteAlbum(ALICE_ALBUM_NAME, this::assertWasDenied);
- loginToClientPage("alice", "alice");
- clientPage.accountRevokeResource("Alice-Family-Album", "jdoe");
+ loginToClientPage(aliceUser);
+ clientPage.accountRevokeResource(ALICE_ALBUM_NAME, "jdoe");
- loginToClientPage("jdoe", "jdoe");
- clientPage.viewAllAlbums();
- clientPage.viewAlbum("Alice-Family-Album", true);
+ // get back to clientPage and init javascript adapter in order to log out correctly
+ clientPage.navigateTo();
+ testExecutor.init(defaultArguments(), this::assertInitNotAuth)
+ .login()
+ .init(defaultArguments(), this::assertSuccessfullyLoggedIn);
+
+ loginToClientPage(jdoeUser);
+ clientPage.viewAlbum(ALICE_ALBUM_NAME, this::assertWasDenied);
}
private void importResourceServerSettings() throws FileNotFoundException {
@@ -731,41 +730,23 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd
return clients.get(resourceServer.getId());
}
- private void deleteAllCookiesForClientPage() {
- jsDriver.manage().deleteAllCookies();
- }
+ private void loginToClientPage(UserRepresentation user, String... scopes) throws InterruptedException {
+ log.debugf("--logging in as {0} with password: {1}; scopes: {2}", user.getUsername(), user.getCredentials().get(0).getValue(), Arrays.toString(scopes));
- private void loginToClientPage(String username, String password, String... scopes) throws InterruptedException {
- log.debugf("--logging in as {0} with password: {1}; scopes: {2}", username, password, Arrays.toString(scopes));
+ if (testExecutor.isLoggedIn()) {
+ testExecutor.logout(this::assertOnTestAppUrl);
+ jsDriver.manage().deleteAllCookies();
- clientPage.navigateTo();
- if (jsDriver.getCurrentUrl().startsWith(clientPage.toString())) {
- try {
- clientPage.logOut();
- } catch (NoSuchElementException ex) {
- if ("phantomjs".equals(System.getProperty("js.browser"))) {
- // PhantomJS is broken, it can't logout using sign out button sometimes, we have to clean sessions and remove cookies
- adminClient.realm(REALM_NAME).logoutAll();
-
- jsDriverTestRealmLoginPage.navigateTo();
- driver.manage().deleteAllCookies();
-
- clientPage.navigateTo();
- driver.manage().deleteAllCookies();
-
- clientPage.navigateTo();
- // Check for correct logout
- assertCurrentUrlStartsWithLoginUrlOf(jsDriverTestRealmLoginPage);
- } else {
- throw ex;
- }
- }
+ jsDriver.navigate().to(testRealmLoginPage.toString());
+ waitForPageToLoad();
+ jsDriver.manage().deleteAllCookies();
}
clientPage.navigateTo();
- waitForPageToLoad();
- clientPage.login(username, password, scopes);
- waitUntilElement(By.linkText("Sign Out")).is().clickable();
+ testExecutor.init(defaultArguments(), this::assertInitNotAuth)
+ .login(this::assertOnLoginPage)
+ .loginFormWithScopesWithPossibleConsentPage(user, this::assertOnTestAppUrl, oAuthGrantPage, scopes)
+ .init(defaultArguments(), this::assertSuccessfullyLoggedIn);
}
private void setManageAlbumScopeRequired() {
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractPhotozJavascriptExecutorTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractPhotozJavascriptExecutorTest.java
new file mode 100644
index 0000000..030ad72
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractPhotozJavascriptExecutorTest.java
@@ -0,0 +1,108 @@
+package org.keycloak.testsuite.adapter.example.authorization;
+
+import org.jboss.arquillian.drone.api.annotation.Drone;
+import org.jboss.arquillian.graphene.page.Page;
+import org.junit.Before;
+import org.keycloak.representations.idm.UserRepresentation;
+import org.keycloak.testsuite.Assert;
+import org.keycloak.testsuite.adapter.AbstractExampleAdapterTest;
+import org.keycloak.testsuite.adapter.javascript.AbstractJavascriptTest;
+import org.keycloak.testsuite.auth.page.login.OAuthGrant;
+import org.keycloak.testsuite.auth.page.login.OIDCLogin;
+import org.keycloak.testsuite.util.JavascriptBrowser;
+import org.keycloak.testsuite.util.UserBuilder;
+import org.keycloak.testsuite.util.javascript.JSObjectBuilder;
+import org.keycloak.testsuite.util.javascript.JavascriptStateValidator;
+import org.keycloak.testsuite.util.javascript.ResponseValidator;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWith;
+import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
+
+/**
+ * @author mhajas
+ */
+public abstract class AbstractPhotozJavascriptExecutorTest extends AbstractExampleAdapterTest {
+
+ @FunctionalInterface
+ interface QuadFunction<T, U, V, W> {
+ void apply(T a, U b, V c, W d);
+ }
+
+ protected static final String REALM_NAME = "photoz";
+
+ @Page
+ @JavascriptBrowser
+ protected OIDCLogin jsDriverTestRealmLoginPage;
+
+ @Page
+ @JavascriptBrowser
+ private OAuthGrant oAuthGrantPage;
+
+ @Drone
+ @JavascriptBrowser
+ protected WebDriver jsDriver;
+
+ protected UserRepresentation aliceUser = UserBuilder.create().username("alice").password("alice").build();
+
+ protected UserRepresentation adminUser = UserBuilder.create().username("admin").password("admin").build();
+
+ protected UserRepresentation jdoeUser = UserBuilder.create().username("jdoe").password("jdoe").build();
+
+ @Before
+ public void setDefaultValues() {
+ jsDriverTestRealmLoginPage.setAuthRealm(REALM_NAME);
+ }
+
+ protected <T> JavascriptStateValidator buildFunction(QuadFunction<T, WebDriver, Object, WebElement> f, T x) {
+ return (y,z,w) -> f.apply(x, y, z, w);
+ }
+
+ public void assertOutputContains(String value, WebDriver driver1, Object output, WebElement events) {
+ if (output instanceof WebElement) {
+ waitUntilElement((WebElement) output).text().contains(value);
+ } else {
+ Assert.assertThat((String) output, containsString(value));
+ }
+ }
+
+ protected JSObjectBuilder defaultArguments() {
+ return JSObjectBuilder.create().defaultSettings();
+ }
+
+ protected void assertSuccessfullyLoggedIn(WebDriver driver1, Object output, WebElement events) {
+ buildFunction(this::assertOutputContains, "Init Success (Authenticated)").validate(driver1, output, events);
+ }
+
+ protected void assertInitNotAuth(WebDriver driver1, Object output, WebElement events) {
+ buildFunction(this::assertOutputContains, "Init Success (Not Authenticated)").validate(driver1, output, events);
+ }
+
+ protected void assertOnLoginPage(WebDriver driver1, Object output, WebElement events) {
+ waitUntilElement(By.tagName("body")).is().present();
+ try {
+ assertCurrentUrlStartsWith(jsDriverTestRealmLoginPage, driver1);
+ } catch (AssertionError e) {
+ System.out.println("Test");
+ throw e;
+ }
+ }
+
+ protected JavascriptStateValidator all(JavascriptStateValidator[] toValidate) {
+ return ((driver1, output, events) -> {
+ for (JavascriptStateValidator val : toValidate) {
+ val.validate(driver1, output, events);
+ }
+ });
+ }
+ protected ResponseValidator all(ResponseValidator[] toValidate) {
+ return ((response) -> {
+ for (ResponseValidator val : toValidate) {
+ val.validate(response);
+ }
+ });
+ }
+}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/PhotozExampleLazyLoadPathsAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/PhotozExampleLazyLoadPathsAdapterTest.java
index 0b8f51d..df41c8b 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/PhotozExampleLazyLoadPathsAdapterTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/PhotozExampleLazyLoadPathsAdapterTest.java
@@ -34,6 +34,7 @@ import org.keycloak.testsuite.arquillian.containers.ContainerConstants;
@AppServerContainer(ContainerConstants.APP_SERVER_EAP)
@AppServerContainer(ContainerConstants.APP_SERVER_EAP6)
@AppServerContainer(ContainerConstants.APP_SERVER_EAP71)
+@AppServerContainer(ContainerConstants.APP_SERVER_UNDERTOW)
public class PhotozExampleLazyLoadPathsAdapterTest extends AbstractPhotozExampleAdapterTest {
@Deployment(name = PhotozClientAuthzTestApp.DEPLOYMENT_NAME)
@@ -43,15 +44,7 @@ public class PhotozExampleLazyLoadPathsAdapterTest extends AbstractPhotozExample
@Deployment(name = RESOURCE_SERVER_ID, managed = false, testable = false)
public static WebArchive deploymentResourceServer() throws IOException {
- WebArchive war = exampleDeployment(RESOURCE_SERVER_ID)
+ return exampleDeployment(RESOURCE_SERVER_ID)
.addAsWebInfResource(new File(TEST_APPS_HOME_DIR + "/photoz/keycloak-lazy-load-path-authz-service.json"), "keycloak.json");
-
- // cannot use EAP6DeploymentArchiveProcessor because the deployment is marked
- // as non managed by arquillian
- if (AppServerTestEnricher.isEAP6AppServer()) {
- updatePersistenceXml(war);
- }
- return war;
}
-
}
\ No newline at end of file
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/PhotozExampleNoLazyLoadPathsAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/PhotozExampleNoLazyLoadPathsAdapterTest.java
index b416d99..36443c0 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/PhotozExampleNoLazyLoadPathsAdapterTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/PhotozExampleNoLazyLoadPathsAdapterTest.java
@@ -33,6 +33,7 @@ import org.keycloak.testsuite.arquillian.containers.ContainerConstants;
@AppServerContainer(ContainerConstants.APP_SERVER_EAP)
@AppServerContainer(ContainerConstants.APP_SERVER_EAP6)
@AppServerContainer(ContainerConstants.APP_SERVER_EAP71)
+@AppServerContainer(ContainerConstants.APP_SERVER_UNDERTOW)
public class PhotozExampleNoLazyLoadPathsAdapterTest extends AbstractPhotozExampleAdapterTest {
@Deployment(name = PhotozClientAuthzTestApp.DEPLOYMENT_NAME)
@@ -42,14 +43,7 @@ public class PhotozExampleNoLazyLoadPathsAdapterTest extends AbstractPhotozExamp
@Deployment(name = RESOURCE_SERVER_ID, managed = false, testable = false)
public static WebArchive deploymentResourceServer() throws IOException {
- WebArchive war = exampleDeployment(RESOURCE_SERVER_ID);
-
- // cannot use EAP6DeploymentArchiveProcessor because the deployment is marked
- // as non managed by arquillian
- if (AppServerTestEnricher.isEAP6AppServer()) {
- updatePersistenceXml(war);
- }
- return war;
+ return exampleDeployment(RESOURCE_SERVER_ID);
}
}
\ No newline at end of file
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/javascript/AbstractJavascriptTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/javascript/AbstractJavascriptTest.java
index 789bebf..a649840 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/javascript/AbstractJavascriptTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/javascript/AbstractJavascriptTest.java
@@ -17,6 +17,8 @@ import org.keycloak.testsuite.util.JavascriptBrowser;
import org.keycloak.testsuite.util.RealmBuilder;
import org.keycloak.testsuite.util.RolesBuilder;
import org.keycloak.testsuite.util.UserBuilder;
+import org.keycloak.testsuite.util.javascript.JavascriptStateValidator;
+import org.keycloak.testsuite.util.javascript.ResponseValidator;
import org.openqa.selenium.By;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.JavascriptExecutor;
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/javascript/JavascriptAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/javascript/JavascriptAdapterTest.java
index 8d62b28..e4a05c1 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/javascript/JavascriptAdapterTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/javascript/JavascriptAdapterTest.java
@@ -24,6 +24,9 @@ import org.keycloak.testsuite.util.JavascriptBrowser;
import org.keycloak.testsuite.util.OAuthClient;
import org.keycloak.testsuite.util.RealmBuilder;
import org.keycloak.testsuite.util.UserBuilder;
+import org.keycloak.testsuite.util.javascript.JSObjectBuilder;
+import org.keycloak.testsuite.util.javascript.JavascriptTestExecutor;
+import org.keycloak.testsuite.util.javascript.XMLHttpRequest;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverException;
@@ -83,10 +86,10 @@ public class JavascriptAdapterTest extends AbstractJavascriptTest {
applicationsPage.setAuthRealm(REALM_NAME);
jsDriver.navigate().to(testAppUrl);
- testExecutor = JavascriptTestExecutor.create(jsDriver, jsDriverTestRealmLoginPage);
waitUntilElement(outputArea).is().present();
assertCurrentUrlStartsWith(testAppUrl, jsDriver);
+ testExecutor = JavascriptTestExecutor.create(jsDriver, jsDriverTestRealmLoginPage);
jsDriver.manage().deleteAllCookies();
@@ -168,6 +171,8 @@ public class JavascriptAdapterTest extends AbstractJavascriptTest {
@Test
public void grantBrowserBasedApp() {
+ Assume.assumeTrue("This test doesn't work with phantomjs", !"phantomjs".equals(System.getProperty("js.browser")));
+
ClientResource clientResource = ApiUtil.findClientResourceByClientId(adminClient.realm(REALM_NAME), CLIENT_ID);
ClientRepresentation client = clientResource.toRepresentation();
client.setConsentRequired(true);
@@ -403,7 +408,7 @@ public class JavascriptAdapterTest extends AbstractJavascriptTest {
List<UserRepresentation> users = adminClient.realm(REALM_NAME).users().search("mhajas", 0, 1);
assertEquals("There should be created user mhajas", 1, users.size());
- assertThat((String) response.get("responseHeaders"), containsString("location: " + authServerContextRootPage.toString() + "/auth/admin/realms/" + REALM_NAME + "/users/" + users.get(0).getId()));
+ assertThat(((String) response.get("responseHeaders")).toLowerCase(), containsString("location: " + authServerContextRootPage.toString() + "/auth/admin/realms/" + REALM_NAME + "/users/" + users.get(0).getId()));
});
}
diff --git a/testsuite/integration-arquillian/util/src/main/java/org/keycloak/testsuite/utils/undertow/UndertowDeployerHelper.java b/testsuite/integration-arquillian/util/src/main/java/org/keycloak/testsuite/utils/undertow/UndertowDeployerHelper.java
index cb91e39..a4f11ee 100644
--- a/testsuite/integration-arquillian/util/src/main/java/org/keycloak/testsuite/utils/undertow/UndertowDeployerHelper.java
+++ b/testsuite/integration-arquillian/util/src/main/java/org/keycloak/testsuite/utils/undertow/UndertowDeployerHelper.java
@@ -75,7 +75,7 @@ public class UndertowDeployerHelper {
di = new DeploymentInfo();
}
- UndertowWarClassLoader classLoader = new UndertowWarClassLoader(UndertowDeployerHelper.class.getClassLoader(), archive);
+ UndertowWarClassLoader classLoader = new UndertowWarClassLoader(Thread.currentThread().getContextClassLoader(), archive);
di.setClassLoader(classLoader);
di.setDeploymentName(archiveName);