keycloak-aplcache
Changes
integration/admin-client/pom.xml 5(+5 -0)
integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ClientAttributeCertificateResource.java 114(+114 -0)
integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ClientResource.java 44(+20 -24)
integration/admin-client/src/main/java/org/keycloak/admin/client/resource/RealmResource.java 2(+1 -1)
services/src/main/java/org/keycloak/services/resources/admin/ClientAttributeCertificateResource.java 63(+3 -60)
testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java 4(+3 -1)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractSessionServletAdapterTest.java 13(+11 -2)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/AbstractClientTest.java 28(+20 -8)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/ClientProtocolMapperTest.java 259(+259 -0)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/ClientRolesTest.java 4(+0 -4)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/CredentialsTest.java 74(+74 -0)
Details
diff --git a/core/src/main/java/org/keycloak/representations/KeyStoreConfig.java b/core/src/main/java/org/keycloak/representations/KeyStoreConfig.java
new file mode 100644
index 0000000..7826694
--- /dev/null
+++ b/core/src/main/java/org/keycloak/representations/KeyStoreConfig.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2016 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.keycloak.representations;
+
+/**
+ * Configuration of KeyStore.
+ *
+ * @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc.
+ */
+public class KeyStoreConfig {
+
+    protected Boolean realmCertificate;
+    protected String storePassword;
+    protected String keyPassword;
+    protected String keyAlias;
+    protected String realmAlias;
+    protected String format;
+
+    public Boolean isRealmCertificate() {
+        return realmCertificate;
+    }
+
+    public void setRealmCertificate(Boolean realmCertificate) {
+        this.realmCertificate = realmCertificate;
+    }
+
+    public String getStorePassword() {
+        return storePassword;
+    }
+
+    public void setStorePassword(String storePassword) {
+        this.storePassword = storePassword;
+    }
+
+    public String getKeyPassword() {
+        return keyPassword;
+    }
+
+    public void setKeyPassword(String keyPassword) {
+        this.keyPassword = keyPassword;
+    }
+
+    public String getKeyAlias() {
+        return keyAlias;
+    }
+
+    public void setKeyAlias(String keyAlias) {
+        this.keyAlias = keyAlias;
+    }
+
+    public String getRealmAlias() {
+        return realmAlias;
+    }
+
+    public void setRealmAlias(String realmAlias) {
+        this.realmAlias = realmAlias;
+    }
+
+    public String getFormat() {
+        return format;
+    }
+
+    public void setFormat(String format) {
+        this.format = format;
+    }
+}
                integration/admin-client/pom.xml 5(+5 -0)
diff --git a/integration/admin-client/pom.xml b/integration/admin-client/pom.xml
index 00b5c27..c0c8899 100755
--- a/integration/admin-client/pom.xml
+++ b/integration/admin-client/pom.xml
@@ -57,6 +57,11 @@
         </dependency>
         <dependency>
             <groupId>org.jboss.resteasy</groupId>
+            <artifactId>resteasy-multipart-provider</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.jboss.resteasy</groupId>
             <artifactId>resteasy-jackson2-provider</artifactId>
             <scope>provided</scope>
         </dependency>
                diff --git a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ClientAttributeCertificateResource.java b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ClientAttributeCertificateResource.java
new file mode 100644
index 0000000..30d3bfb
--- /dev/null
+++ b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ClientAttributeCertificateResource.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2016 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.keycloak.admin.client.resource;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.UriInfo;
+import org.jboss.resteasy.annotations.cache.NoCache;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput;
+import org.keycloak.representations.KeyStoreConfig;
+import org.keycloak.representations.idm.CertificateRepresentation;
+
+/**
+ *
+ * @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc.
+ */
+public interface ClientAttributeCertificateResource {
+
+    /**
+     * Get key info
+     *
+     * @return
+     */
+    @GET
+    @NoCache
+    @Produces(MediaType.APPLICATION_JSON)
+    public CertificateRepresentation getKeyInfo();
+
+    /**
+     * Generate a new certificate with new key pair
+     *
+     * @return
+     */
+    @POST
+    @NoCache
+    @Path("generate")
+    @Produces(MediaType.APPLICATION_JSON)
+    public CertificateRepresentation generate();
+
+    /**
+     * Upload certificate and eventually private key
+     *
+     * @param uriInfo
+     * @param input
+     * @return
+     */
+    @POST
+    @Path("upload")
+    @Consumes(MediaType.MULTIPART_FORM_DATA)
+    @Produces(MediaType.APPLICATION_JSON)
+    public CertificateRepresentation uploadJks(@Context final UriInfo uriInfo, MultipartFormDataInput input);
+
+    /**
+     * Upload only certificate, not private key
+     *
+     * @param uriInfo
+     * @param input
+     * @return
+     */
+    @POST
+    @Path("upload-certificate")
+    @Consumes(MediaType.MULTIPART_FORM_DATA)
+    @Produces(MediaType.APPLICATION_JSON)
+    public CertificateRepresentation uploadJksCertificate(@Context final UriInfo uriInfo, MultipartFormDataInput input);
+
+    /**
+     * Get a keystore file for the client, containing private key and public certificate
+     *
+     * @param config Keystore configuration as JSON
+     * @return
+     */
+    @POST
+    @NoCache
+    @Path("/download")
+    @Produces(MediaType.APPLICATION_OCTET_STREAM)
+    @Consumes(MediaType.APPLICATION_JSON)
+    public byte[] getKeystore(final KeyStoreConfig config);
+
+    /**
+     * Generate a new keypair and certificate, and get the private key file
+     *
+     * Generates a keypair and certificate and serves the private key in a specified keystore format.
+     * Only generated public certificate is saved in Keycloak DB - the private key is not.
+     *
+     * @param config Keystore configuration as JSON
+     * @return
+     */
+    @POST
+    @NoCache
+    @Path("/generate-and-download")
+    @Produces(MediaType.APPLICATION_OCTET_STREAM)
+    @Consumes(MediaType.APPLICATION_JSON)
+    public byte[] generateAndGetKeystore(final KeyStoreConfig config);
+}
                diff --git a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ClientResource.java b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ClientResource.java
index ee1c69a..644cc7a 100755
--- a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ClientResource.java
+++ b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ClientResource.java
@@ -34,7 +34,6 @@ import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.MediaType;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 
 /**
  * @author rodrigo.sasaki@icarros.com.br
@@ -55,21 +54,6 @@ public interface ClientResource {
     @DELETE
     public void remove();
 
-    @GET
-    @Path("allowed-origins")
-    @Produces(MediaType.APPLICATION_JSON)
-    public Set<String> getAllowedOrigins();
-
-    @PUT
-    @Path("allowed-origins")
-    @Consumes(MediaType.APPLICATION_JSON)
-    public void updateAllowedOrigins(Set<String> allowedOrigins);
-
-    @DELETE
-    @Path("allowed-origins")
-    @Consumes(MediaType.APPLICATION_JSON)
-    public void removeAllowedOrigins(Set<String> originsToRemove);
-
     @POST
     @Path("client-secret")
     @Produces(MediaType.APPLICATION_JSON)
@@ -80,19 +64,31 @@ public interface ClientResource {
     @Produces(MediaType.APPLICATION_JSON)
     public CredentialRepresentation getSecret();
 
+    /**
+     * Generate a new registration access token for the client
+     *
+     * @return
+     */
+    @Path("registration-access-token")
+    @POST
+    @Produces(MediaType.APPLICATION_JSON)
+    @Consumes(MediaType.APPLICATION_JSON)
+    public ClientRepresentation regenerateRegistrationAccessToken();
+
+    /**
+     * Get representation of certificate resource
+     *
+     * @param attributePrefix
+     * @return
+     */
+    @Path("certificates/{attr}")
+    public ClientAttributeCertificateResource getCertficateResource(@PathParam("attr") String attributePrefix);
+
     @GET
     @NoCache
     @Path("installation/providers/{providerId}")
     public String getInstallationProvider(@PathParam("providerId") String providerId);
 
-    @POST
-    @Path("logout-all")
-    public void logoutAllUsers();
-
-    @POST
-    @Path("logout-user/{username}")
-    public void logoutUser(@PathParam("username") String username);
-
     @Path("session-count")
     @GET
     @Produces(MediaType.APPLICATION_JSON)
                diff --git a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/RealmResource.java b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/RealmResource.java
index 15ca073..86548ec 100644
--- a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/RealmResource.java
+++ b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/RealmResource.java
@@ -149,7 +149,7 @@ public interface RealmResource {
     @Consumes(MediaType.APPLICATION_JSON)
     @Produces(MediaType.APPLICATION_JSON)
     public Response partialImport(PartialImportRepresentation rep);
-    
+
     @Path("authentication")
     @Consumes(MediaType.APPLICATION_JSON)
     AuthenticationManagementResource flows();
                diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ClientAttributeCertificateResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ClientAttributeCertificateResource.java
index 6633a68..bea79a0 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ClientAttributeCertificateResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ClientAttributeCertificateResource.java
@@ -28,6 +28,7 @@ import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.utils.KeycloakModelUtils;
+import org.keycloak.representations.KeyStoreConfig;
 import org.keycloak.representations.idm.CertificateRepresentation;
 import org.keycloak.services.ErrorResponseException;
 import org.keycloak.common.util.PemUtils;
@@ -57,7 +58,7 @@ import java.util.Map;
  * @version $Revision: 1 $
  */
 public class ClientAttributeCertificateResource {
-    
+
     public static final String PRIVATE_KEY = "private.key";
     public static final String X509CERTIFICATE = "certificate";
 
@@ -112,7 +113,7 @@ public class ClientAttributeCertificateResource {
 
         client.setAttribute(privateAttribute, info.getPrivateKey());
         client.setAttribute(certificateAttribute, info.getCertificate());
-        
+
         adminEvent.operation(OperationType.ACTION).resourcePath(session.getContext().getUri()).representation(info).success();
 
         return info;
@@ -225,64 +226,6 @@ public class ClientAttributeCertificateResource {
         return info;
     }
 
-
-    public static class KeyStoreConfig {
-        protected Boolean realmCertificate;
-        protected String storePassword;
-        protected String keyPassword;
-        protected String keyAlias;
-        protected String realmAlias;
-        protected String format;
-
-        public Boolean isRealmCertificate() {
-            return realmCertificate;
-        }
-
-        public void setRealmCertificate(Boolean realmCertificate) {
-            this.realmCertificate = realmCertificate;
-        }
-
-        public String getStorePassword() {
-            return storePassword;
-        }
-
-        public void setStorePassword(String storePassword) {
-            this.storePassword = storePassword;
-        }
-
-        public String getKeyPassword() {
-            return keyPassword;
-        }
-
-        public void setKeyPassword(String keyPassword) {
-            this.keyPassword = keyPassword;
-        }
-
-        public String getKeyAlias() {
-            return keyAlias;
-        }
-
-        public void setKeyAlias(String keyAlias) {
-            this.keyAlias = keyAlias;
-        }
-
-        public String getRealmAlias() {
-            return realmAlias;
-        }
-
-        public void setRealmAlias(String realmAlias) {
-            this.realmAlias = realmAlias;
-        }
-
-        public String getFormat() {
-            return format;
-        }
-
-        public void setFormat(String format) {
-            this.format = format;
-        }
-    }
-
     /**
      * Get a keystore file for the client, containing private key and public certificate
      *
                diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ClientResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ClientResource.java
index 790dd2b..09c3dee 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ClientResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ClientResource.java
@@ -45,7 +45,6 @@ import org.keycloak.services.managers.RealmManager;
 import org.keycloak.services.managers.ResourceAdminManager;
 import org.keycloak.services.resources.KeycloakApplication;
 import org.keycloak.services.ErrorResponse;
-import org.keycloak.util.JsonSerialization;
 import org.keycloak.common.util.Time;
 
 import javax.ws.rs.Consumes;
@@ -62,12 +61,11 @@ import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriInfo;
 
-import java.io.IOException;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
+
 import static java.lang.Boolean.TRUE;
 
 
@@ -172,54 +170,6 @@ public class ClientResource {
         return provider.generateInstallation(session, realm, client, keycloak.getBaseUri(uriInfo));
     }
 
-
-    /**
-     * Get keycloak.json file
-     *
-     * this method is deprecated, see getInstallationProvider
-     *
-     * Returns a keycloak.json file to be used to configure the adapter of the specified client.
-     *
-     * @return
-     * @throws IOException
-     */
-    @Deprecated
-    @GET
-    @NoCache
-    @Path("installation/json")
-    @Produces(MediaType.APPLICATION_JSON)
-    public String getInstallation() throws IOException {
-        auth.requireView();
-
-        ClientManager clientManager = new ClientManager(new RealmManager(session));
-        Object rep = clientManager.toInstallationRepresentation(realm, client, getKeycloakApplication().getBaseUri(uriInfo));
-
-        // TODO Temporary solution to pretty-print
-        return JsonSerialization.mapper.writerWithDefaultPrettyPrinter().writeValueAsString(rep);
-    }
-
-    /**
-     * Get adapter configuration XML for JBoss / Wildfly Keycloak subsystem
-     *
-     * this method is deprecated, see getInstallationProvider
-     *
-     * Returns XML that can be included in the JBoss / Wildfly Keycloak subsystem to configure the adapter of that client.
-     *
-     * @return
-     * @throws IOException
-     */
-    @Deprecated
-    @GET
-    @NoCache
-    @Path("installation/jboss")
-    @Produces(MediaType.TEXT_PLAIN)
-    public String getJBossInstallation() throws IOException {
-        auth.requireView();
-
-        ClientManager clientManager = new ClientManager(new RealmManager(session));
-        return clientManager.toJBossSubsystemConfig(realm, client, getKeycloakApplication().getBaseUri(uriInfo));
-    }
-
     /**
      * Delete the client
      *
@@ -307,64 +257,6 @@ public class ClientResource {
     }
 
     /**
-     * Get allowed origins
-     *
-     * This is used for CORS requests.  Access tokens will have
-     * their allowedOrigins claim set to this value for tokens created for this client.
-     *
-     * @return
-     */
-    @Path("allowed-origins")
-    @GET
-    @NoCache
-    @Produces(MediaType.APPLICATION_JSON)
-    public Set<String> getAllowedOrigins()
-    {
-        auth.requireView();
-        return client.getWebOrigins();
-    }
-
-    /**
-     * Update allowed origins
-     *
-     * This is used for CORS requests.  Access tokens will have
-     * their allowedOrigins claim set to this value for tokens created for this client.
-     *
-     * @param allowedOrigins
-     */
-    @Path("allowed-origins")
-    @PUT
-    @Consumes(MediaType.APPLICATION_JSON)
-    public void updateAllowedOrigins(Set<String> allowedOrigins)
-    {
-        auth.requireManage();
-
-        client.setWebOrigins(allowedOrigins);
-        adminEvent.operation(OperationType.UPDATE).resourcePath(uriInfo).representation(client).success();
-    }
-
-    /**
-     * Delete the specified origins from current allowed origins
-     *
-     * This is used for CORS requests.  Access tokens will have
-     * their allowedOrigins claim set to this value for tokens created for this client.
-     *
-     * @param allowedOrigins List of origins to delete
-     */
-    @Path("allowed-origins")
-    @DELETE
-    @Consumes(MediaType.APPLICATION_JSON)
-    public void deleteAllowedOrigins(Set<String> allowedOrigins)
-    {
-        auth.requireManage();
-
-        for (String origin : allowedOrigins) {
-            client.removeWebOrigin(origin);
-        }
-        adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo).success();
-    }
-
-    /**
      * Get a user dedicated to the service account
      *
      * @return
@@ -507,41 +399,6 @@ public class ClientResource {
         return sessions;
     }
 
-
-    /**
-     * Logout all sessions
-     *
-     * If the client has an admin URL, invalidate all sessions associated with that client directly.
-     *
-     */
-    @Path("logout-all")
-    @POST
-    public GlobalRequestResult logoutAll() {
-        auth.requireManage();
-        adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo).success();
-        return new ResourceAdminManager(session).logoutClient(uriInfo.getRequestUri(), realm, client);
-
-    }
-
-    /**
-     * Logout the user by username
-     *
-     * If the client has an admin URL, invalidate the sessions for a particular user directly.
-     *
-     */
-    @Path("logout-user/{username}")
-    @POST
-    public void logout(final @PathParam("username") String username) {
-        auth.requireManage();
-        UserModel user = session.users().getUserByUsername(username, realm);
-        if (user == null) {
-            throw new NotFoundException("User not found");
-        }
-        adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo).success();
-        new ResourceAdminManager(session).logoutUserFromClient(uriInfo.getRequestUri(), realm, client, user);
-
-    }
-
     /**
      * Register a cluster node with the client
      *
                diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java
index 7b0d9d3..7097588 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java
@@ -59,6 +59,7 @@ import java.net.URI;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.atomic.AtomicInteger;
+import org.keycloak.representations.idm.UserRepresentation;
 
 /**
  * Tests Undertow Adapter
@@ -598,7 +599,8 @@ public class AdapterTestStrategy extends ExternalResource {
 
         // logout mposolda with admin client
         Keycloak keycloakAdmin = Keycloak.getInstance(AUTH_SERVER_URL, "master", "admin", "admin", Constants.ADMIN_CLI_CLIENT_ID);
-        ApiUtil.findClientByClientId(keycloakAdmin.realm("demo"), "session-portal").logoutUser("mposolda");
+        UserRepresentation mposolda = keycloakAdmin.realm("demo").users().search("mposolda", null, null, null, null, null).get(0);
+        keycloakAdmin.realm("demo").users().get(mposolda.getId()).logout();
 
         // bburke should be still logged with original httpSession in our browser window
         driver.navigate().to(APP_SERVER_BASE_URL + "/session-portal");
                diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractSessionServletAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractSessionServletAdapterTest.java
index a027234..0bce8a6 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractSessionServletAdapterTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractSessionServletAdapterTest.java
@@ -23,22 +23,29 @@ import org.jboss.arquillian.drone.api.annotation.Drone;
 import org.jboss.arquillian.graphene.page.Page;
 import org.jboss.shrinkwrap.api.spec.WebArchive;
 import org.junit.After;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
+
 import org.junit.Test;
 import org.keycloak.OAuth2Constants;
 import org.keycloak.admin.client.resource.ClientResource;
 import org.keycloak.protocol.oidc.OIDCLoginProtocolService;
 import org.keycloak.representations.idm.ClientRepresentation;
 import org.keycloak.representations.idm.RealmRepresentation;
+import org.keycloak.representations.idm.UserRepresentation;
 import org.keycloak.testsuite.adapter.page.SessionPortal;
+
 import static org.keycloak.testsuite.auth.page.AuthRealm.DEMO;
+
 import org.keycloak.testsuite.auth.page.account.Sessions;
 import org.keycloak.testsuite.auth.page.login.Login;
+
 import static org.keycloak.testsuite.admin.ApiUtil.findClientResourceByClientId;
 import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlEquals;
 import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWithLoginUrlOf;
+
 import org.keycloak.testsuite.util.SecondBrowser;
 import org.openqa.selenium.By;
 import org.openqa.selenium.WebDriver;
@@ -156,9 +163,11 @@ public abstract class AbstractSessionServletAdapterTest extends AbstractServlets
     public void testAdminApplicationLogout() {
         // login as bburke
         loginAndCheckSession(driver, testRealmLoginPage);
+
         // logout mposolda with admin client
-        findClientResourceByClientId(testRealmResource(), "session-portal")
-                .logoutUser("mposolda");
+        UserRepresentation mposolda = testRealmResource().users().search("mposolda", null, null, null, null, null).get(0);
+        testRealmResource().users().get(mposolda.getId()).logout();
+        
         // bburke should be still logged with original httpSession in our browser window
         sessionPortalPage.navigateTo();
         assertEquals(driver.getCurrentUrl(), sessionPortalPage.toString());
                diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/AbstractClientTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/AbstractClientTest.java
index 7059318..9913c17 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/AbstractClientTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/AbstractClientTest.java
@@ -17,10 +17,12 @@
 
 package org.keycloak.testsuite.admin.client;
 
+import java.util.List;
 import javax.ws.rs.core.Response;
 import org.keycloak.admin.client.resource.ClientResource;
 import org.keycloak.representations.idm.ClientRepresentation;
 import org.keycloak.representations.idm.RealmRepresentation;
+import org.keycloak.representations.idm.UserRepresentation;
 import org.keycloak.testsuite.AbstractAuthTest;
 import org.keycloak.testsuite.admin.ApiUtil;
 
@@ -34,29 +36,35 @@ public abstract class AbstractClientTest extends AbstractAuthTest {
         return testRealmResource().toRepresentation();
     }
 
-    protected void createOidcClient(String name) {
+    // returns UserRepresentation retrieved from server, with all fields, including id
+    protected UserRepresentation getFullUserRep(String userName) {
+        List<UserRepresentation> results = testRealmResource().users().search(userName, null, null, null, null, null);
+        if (results.size() != 1) throw new RuntimeException("Did not find single user with username " + userName);
+        return results.get(0);
+    }
+
+    protected String createOidcClient(String name) {
         ClientRepresentation clientRep = new ClientRepresentation();
         clientRep.setClientId(name);
         clientRep.setName(name);
         clientRep.setRootUrl("foo");
         clientRep.setProtocol("openid-connect");
-        createClient(clientRep);
+        return createClient(clientRep);
     }
 
-        protected void createSamlClient(String name) {
+    protected String createSamlClient(String name) {
         ClientRepresentation clientRep = new ClientRepresentation();
         clientRep.setClientId(name);
         clientRep.setName(name);
         clientRep.setProtocol("saml");
         clientRep.setAdminUrl("samlEndpoint");
-        createClient(clientRep);
+        return createClient(clientRep);
     }
 
-    protected void createClient(ClientRepresentation clientRep) {
+    protected String createClient(ClientRepresentation clientRep) {
         Response resp = testRealmResource().clients().create(clientRep);
-        // for some reason, findAll() will later fail unless readEntity is called here
-        resp.readEntity(String.class);
-        //testRealmResource().clients().findAll();
+        resp.close();
+        return ApiUtil.getCreatedId(resp);
     }
 
     protected ClientRepresentation findClientRepresentation(String name) {
@@ -69,4 +77,8 @@ public abstract class AbstractClientTest extends AbstractAuthTest {
         return ApiUtil.findClientResourceByName(testRealmResource(), name);
     }
 
+    protected ClientResource findClientResourceById(String id) {
+        return ApiUtil.findClientResourceByClientId(testRealmResource(), id);
+    }
+
 }
                diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/ClientProtocolMapperTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/ClientProtocolMapperTest.java
new file mode 100644
index 0000000..c94e3d6
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/ClientProtocolMapperTest.java
@@ -0,0 +1,259 @@
+/*
+ * Copyright 2016 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.keycloak.testsuite.admin.client;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.ws.rs.NotFoundException;
+import javax.ws.rs.core.Response;
+import org.junit.Before;
+import org.junit.Test;
+import org.keycloak.admin.client.resource.ClientResource;
+import org.keycloak.admin.client.resource.ProtocolMappersResource;
+import org.keycloak.representations.idm.ProtocolMapperRepresentation;
+import org.keycloak.testsuite.admin.ApiUtil;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+/**
+ *
+ * @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc.
+ */
+public class ClientProtocolMapperTest extends AbstractClientTest {
+
+    private ClientResource oidcClientRsc;
+    private ProtocolMappersResource oidcMappersRsc;
+    private ClientResource samlClientRsc;
+    private ProtocolMappersResource samlMappersRsc;
+
+    private Map<String, List<ProtocolMapperRepresentation>> builtinMappers;
+
+    @Before
+    public void init() {
+        createOidcClient("oidcMapperClient");
+        oidcClientRsc = findClientResource("oidcMapperClient");
+        oidcMappersRsc = oidcClientRsc.getProtocolMappers();
+
+        createSamlClient("samlMapperClient");
+        samlClientRsc = findClientResource("samlMapperClient");
+        samlMappersRsc = samlClientRsc.getProtocolMappers();
+
+        builtinMappers = adminClient.serverInfo().getInfo().getBuiltinProtocolMappers();
+    }
+
+    private ProtocolMapperRepresentation makeMapper(String protocol, String name, String mapperType, Map<String, String> config) {
+        ProtocolMapperRepresentation rep = new ProtocolMapperRepresentation();
+        rep.setProtocol(protocol);
+        rep.setName(name);
+        rep.setProtocolMapper(mapperType);
+        rep.setConfig(config);
+        rep.setConsentRequired(true);
+        rep.setConsentText("Test Consent Text");
+        return rep;
+    }
+
+    private ProtocolMapperRepresentation makeSamlMapper(String name) {
+        Map<String, String> config = new HashMap<>();
+        config.put("role", "account.view-profile");
+        config.put("new.role.name", "new-role-name");
+        return makeMapper("saml", name, "saml-role-name-mapper", config);
+    }
+
+    private ProtocolMapperRepresentation makeOidcMapper(String name) {
+        Map<String, String> config = new HashMap<>();
+        config.put("role", "myrole");
+        return makeMapper("openid-connect", name, "oidc-hardcoded-role-mapper", config);
+    }
+
+    private void assertEqualMappers(ProtocolMapperRepresentation original, ProtocolMapperRepresentation created) {
+        assertNotNull(created);
+        assertEquals(original.getName(), created.getName());
+        assertEquals(original.getConfig(), created.getConfig());
+        assertEquals(original.getConsentText(), created.getConsentText());
+        assertEquals(original.isConsentRequired(), created.isConsentRequired());
+        assertEquals(original.getProtocol(), created.getProtocol());
+        assertEquals(original.getProtocolMapper(), created.getProtocolMapper());
+    }
+
+    @Test
+    public void testGetMappersList() {
+        assertFalse(oidcMappersRsc.getMappers().isEmpty());
+        assertFalse(samlMappersRsc.getMappers().isEmpty());
+    }
+
+    private boolean containsMapper(List<ProtocolMapperRepresentation> mappers, ProtocolMapperRepresentation mapper) {
+        for (ProtocolMapperRepresentation listedMapper : mappers) {
+            if (listedMapper.getName().equals(mapper.getName())) return true;
+        }
+
+        return false;
+    }
+
+    private List<ProtocolMapperRepresentation> mappersToAdd(List<ProtocolMapperRepresentation> oldMappers,
+                                                            List<ProtocolMapperRepresentation> builtins) {
+        List<ProtocolMapperRepresentation> mappersToAdd = new ArrayList<>();
+        for (ProtocolMapperRepresentation builtin : builtins) {
+            if (!containsMapper(oldMappers, builtin)) mappersToAdd.add(builtin);
+        }
+
+        return mappersToAdd;
+    }
+
+    private void testAddAllBuiltinMappers(ProtocolMappersResource resource, String resourceName) {
+        List<ProtocolMapperRepresentation> oldMappers = resource.getMappersPerProtocol(resourceName);
+        List<ProtocolMapperRepresentation> builtins = builtinMappers.get(resourceName);
+
+        List<ProtocolMapperRepresentation> mappersToAdd = mappersToAdd(oldMappers, builtins);
+
+        // This is used by admin console to add builtin mappers
+        resource.createMapper(mappersToAdd);
+
+        List<ProtocolMapperRepresentation> newMappers = resource.getMappersPerProtocol(resourceName);
+        assertEquals(oldMappers.size() + mappersToAdd.size(), newMappers.size());
+
+        for (ProtocolMapperRepresentation rep : mappersToAdd) {
+            assertTrue(containsMapper(newMappers, rep));
+        }
+    }
+
+    @Test
+    public void testCreateOidcMappersFromList() {
+        testAddAllBuiltinMappers(oidcMappersRsc, "openid-connect");
+    }
+
+    @Test
+    public void testCreateSamlMappersFromList() {
+        testAddAllBuiltinMappers(samlMappersRsc, "saml");
+    }
+
+    @Test
+    public void testCreateSamlProtocolMapper() {
+
+        //{"protocol":"saml",
+        // "config":{"role":"account.view-profile","new.role.name":"new-role-name"},
+        // "consentRequired":true,
+        // "consentText":"My consent text",
+        // "name":"saml-role-name-maper",
+        // "protocolMapper":"saml-role-name-mapper"}
+        ProtocolMapperRepresentation rep = makeSamlMapper("saml-role-name-mapper");
+
+        int totalMappers = samlMappersRsc.getMappers().size();
+        int totalSamlMappers = samlMappersRsc.getMappersPerProtocol("saml").size();
+        Response resp = samlMappersRsc.createMapper(rep);
+        resp.close();
+        assertEquals(totalMappers + 1, samlMappersRsc.getMappers().size());
+        assertEquals(totalSamlMappers + 1, samlMappersRsc.getMappersPerProtocol("saml").size());
+
+        String createdId = ApiUtil.getCreatedId(resp);
+        ProtocolMapperRepresentation created = samlMappersRsc.getMapperById(createdId);
+        assertEqualMappers(rep, created);
+    }
+
+    @Test
+    public void testCreateOidcProtocolMapper() {
+        //{"protocol":"openid-connect",
+        // "config":{"role":"myrole"},
+        // "consentRequired":true,
+        // "consentText":"My consent text",
+        // "name":"oidc-hardcoded-role-mapper",
+        // "protocolMapper":"oidc-hardcoded-role-mapper"}
+        ProtocolMapperRepresentation rep = makeOidcMapper("oidc-hardcoded-role-mapper");
+
+        int totalMappers = oidcMappersRsc.getMappers().size();
+        int totalOidcMappers = oidcMappersRsc.getMappersPerProtocol("openid-connect").size();
+        Response resp = oidcMappersRsc.createMapper(rep);
+        resp.close();
+        assertEquals(totalMappers + 1, oidcMappersRsc.getMappers().size());
+        assertEquals(totalOidcMappers + 1, oidcMappersRsc.getMappersPerProtocol("openid-connect").size());
+
+        String createdId = ApiUtil.getCreatedId(resp);
+        ProtocolMapperRepresentation created = oidcMappersRsc.getMapperById(createdId);//findByName(samlMappersRsc, "saml-role-name-mapper");
+        assertEqualMappers(rep, created);
+    }
+
+    @Test
+    public void testUpdateSamlMapper() {
+        ProtocolMapperRepresentation rep = makeSamlMapper("saml-role-name-mapper2");
+
+        Response resp = samlMappersRsc.createMapper(rep);
+        resp.close();
+
+        String createdId = ApiUtil.getCreatedId(resp);
+
+        rep.getConfig().put("role", "account.manage-account");
+        rep.setId(createdId);
+        rep.setConsentRequired(false);
+        samlMappersRsc.update(createdId, rep);
+
+        ProtocolMapperRepresentation updated = samlMappersRsc.getMapperById(createdId);
+        assertEqualMappers(rep, updated);
+    }
+
+    @Test
+    public void testUpdateOidcMapper() {
+        ProtocolMapperRepresentation rep = makeOidcMapper("oidc-hardcoded-role-mapper2");
+
+        Response resp = oidcMappersRsc.createMapper(rep);
+        resp.close();
+
+        String createdId = ApiUtil.getCreatedId(resp);
+
+        rep.getConfig().put("role", "myotherrole");
+        rep.setId(createdId);
+        rep.setConsentRequired(false);
+        oidcMappersRsc.update(createdId, rep);
+
+        ProtocolMapperRepresentation updated = oidcMappersRsc.getMapperById(createdId);
+        assertEqualMappers(rep, updated);
+    }
+
+    @Test (expected = NotFoundException.class)
+    public void testDeleteSamlMapper() {
+        ProtocolMapperRepresentation rep = makeSamlMapper("saml-role-name-mapper3");
+
+        Response resp = samlMappersRsc.createMapper(rep);
+        resp.close();
+
+        String createdId = ApiUtil.getCreatedId(resp);
+
+        samlMappersRsc.delete(createdId);
+
+        samlMappersRsc.getMapperById(createdId);
+    }
+
+    @Test (expected = NotFoundException.class)
+    public void testDeleteOidcMapper() {
+        ProtocolMapperRepresentation rep = makeOidcMapper("oidc-hardcoded-role-mapper3");
+
+        Response resp = oidcMappersRsc.createMapper(rep);
+        resp.close();
+
+        String createdId = ApiUtil.getCreatedId(resp);
+
+        oidcMappersRsc.delete(createdId);
+
+        oidcMappersRsc.getMapperById(createdId);
+    }
+
+}
                diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/ClientRolesTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/ClientRolesTest.java
index 9180f15..d551c54 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/ClientRolesTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/ClientRolesTest.java
@@ -48,10 +48,6 @@ public class ClientRolesTest extends AbstractClientTest {
         return role;
     }
 
-  /*  private boolean hasRole(RolesResource rolesRsc, String name) {
-        return rolesRsc.get(name) != null;
-    }*/
-
     private boolean hasRole(RolesResource rolesRsc, String name) {
         for (RoleRepresentation role : rolesRsc.list()) {
             if (role.getName().equals(name)) return true;
                diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/CredentialsTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/CredentialsTest.java
new file mode 100644
index 0000000..2b79e50
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/CredentialsTest.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2016 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.keycloak.testsuite.admin.client;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.keycloak.admin.client.resource.ClientAttributeCertificateResource;
+import org.keycloak.admin.client.resource.ClientResource;
+import org.keycloak.representations.idm.CertificateRepresentation;
+import org.keycloak.representations.idm.ClientRepresentation;
+import org.keycloak.representations.idm.CredentialRepresentation;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNull;
+
+/**
+ *
+ * @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc.
+ */
+public class CredentialsTest extends AbstractClientTest {
+
+    private ClientResource accountClient;
+
+    @Before
+    public void init() {
+        accountClient = findClientResourceById("account");
+    }
+
+    @Test
+    public void testGetAndRegenerateSecret() {
+        CredentialRepresentation oldCredential = accountClient.getSecret();
+        CredentialRepresentation newCredential = accountClient.generateNewSecret();
+        assertNotNull(oldCredential);
+        assertNotNull(newCredential);
+        assertNotEquals(newCredential.getValue(), oldCredential.getValue());
+        assertEquals(newCredential.getValue(), accountClient.getSecret().getValue());
+    }
+
+    @Test
+    public void testGetAndRegenerateRegistrationAccessToken() {
+        ClientRepresentation rep = accountClient.toRepresentation();
+        String oldToken = rep.getRegistrationAccessToken();
+        String newToken = accountClient.regenerateRegistrationAccessToken().getRegistrationAccessToken();
+        assertNull(oldToken); // registration access token not saved in ClientRep
+        assertNotNull(newToken); // it's only available via regenerateRegistrationAccessToken()
+        assertNull(accountClient.toRepresentation().getRegistrationAccessToken());
+    }
+
+    @Test
+    public void testGetCertificateResource() {
+        ClientAttributeCertificateResource certRsc = accountClient.getCertficateResource("jwt.credential");
+        CertificateRepresentation cert = certRsc.generate();
+        CertificateRepresentation certFromGet = certRsc.getKeyInfo();
+        assertEquals(cert.getCertificate(), certFromGet.getCertificate());
+        assertEquals(cert.getPrivateKey(), certFromGet.getPrivateKey());
+    }
+}
                diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/SessionTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/SessionTest.java
new file mode 100644
index 0000000..cf15f96
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/SessionTest.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2016 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.keycloak.testsuite.admin.client;
+
+import java.util.List;
+import org.jboss.arquillian.graphene.page.Page;
+import org.junit.Before;
+import org.junit.Test;
+import org.keycloak.admin.client.resource.ClientResource;
+import org.keycloak.representations.idm.UserRepresentation;
+import org.keycloak.representations.idm.UserSessionRepresentation;
+import org.keycloak.testsuite.auth.page.account.AccountManagement;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+/**
+ *
+ * @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc.
+ */
+public class SessionTest extends AbstractClientTest {
+    private static boolean testUserCreated = false;
+
+    @Page
+    protected AccountManagement testRealmAccountManagementPage;
+
+    @Before
+    public void init() {
+        // make user test user exists in test realm
+        if (!testUserCreated) createTestUserWithAdminClient();
+        testUserCreated = true;
+    }
+
+    @Test
+    public void testGetAppSessionCount() {
+        ClientResource accountClient = findClientResourceById("account");
+        int sessionCount = accountClient.getApplicationSessionCount().get("count");
+        assertEquals(0, sessionCount);
+
+        testRealmAccountManagementPage.navigateTo();
+        loginPage.form().login(testUser);
+
+        sessionCount = accountClient.getApplicationSessionCount().get("count");
+        assertEquals(1, sessionCount);
+
+        testRealmAccountManagementPage.signOut();
+
+        sessionCount = accountClient.getApplicationSessionCount().get("count");
+        assertEquals(0, sessionCount);
+    }
+
+    @Test
+    public void testGetUserSessions() {
+        //List<java.util.Map<String, String>> stats = this.testRealmResource().getClientSessionStats();
+        ClientResource account = findClientResourceById("account");
+
+        testRealmAccountManagementPage.navigateTo();
+        loginPage.form().login(testUser);
+
+        List<UserSessionRepresentation> sessions = account.getUserSessions(0, 5);
+        assertEquals(1, sessions.size());
+
+        UserSessionRepresentation rep = sessions.get(0);
+
+        UserRepresentation testUserRep = getFullUserRep(testUser.getUsername());
+        assertEquals(testUserRep.getId(), rep.getUserId());
+        assertEquals(testUserRep.getUsername(), rep.getUsername());
+
+        String clientId = account.toRepresentation().getId();
+        assertEquals("account", rep.getClients().get(clientId));
+        assertNotNull(rep.getIpAddress());
+        assertNotNull(rep.getLastAccess());
+        assertNotNull(rep.getStart());
+
+        testRealmAccountManagementPage.signOut();
+    }
+}
                diff --git a/themes/src/main/resources/theme/base/admin/resources/js/services.js b/themes/src/main/resources/theme/base/admin/resources/js/services.js
index 1ec8513..868ec4d 100755
--- a/themes/src/main/resources/theme/base/admin/resources/js/services.js
+++ b/themes/src/main/resources/theme/base/admin/resources/js/services.js
@@ -952,19 +952,6 @@ module.factory('ClientOfflineSessions', function($resource) {
     });
 });
 
-module.factory('ClientLogoutAll', function($resource) {
-    return $resource(authUrl + '/admin/realms/:realm/clients/:client/logout-all', {
-        realm : '@realm',
-        client : "@client"
-    });
-});
-module.factory('ClientLogoutUser', function($resource) {
-    return $resource(authUrl + '/admin/realms/:realm/clients/:client/logout-user/:user', {
-        realm : '@realm',
-        client : "@client",
-        user : "@user"
-    });
-});
 module.factory('RealmLogoutAll', function($resource) {
     return $resource(authUrl + '/admin/realms/:realm/logout-all', {
         realm : '@realm'