keycloak-aplcache

Merge pull request #3266 from mhajas/KEYCLOAK-3586 KEYCLOAK-3586

9/29/2016 6:13:26 AM

Details

diff --git a/testsuite/integration-arquillian/test-apps/js-console/example-realm.json b/testsuite/integration-arquillian/test-apps/js-console/example-realm.json
index 4e3adca..e90217a 100755
--- a/testsuite/integration-arquillian/test-apps/js-console/example-realm.json
+++ b/testsuite/integration-arquillian/test-apps/js-console/example-realm.json
@@ -19,6 +19,7 @@
             ],
             "realmRoles": [ "user" ],
             "clientRoles": {
+                "realm-management" : [ "view-realm" ],
                 "account": ["view-profile", "manage-account"]
             }
         },{
diff --git a/testsuite/integration-arquillian/test-apps/js-console/src/main/webapp/index.html b/testsuite/integration-arquillian/test-apps/js-console/src/main/webapp/index.html
index 468f98e..1c2b61d 100755
--- a/testsuite/integration-arquillian/test-apps/js-console/src/main/webapp/index.html
+++ b/testsuite/integration-arquillian/test-apps/js-console/src/main/webapp/index.html
@@ -29,6 +29,7 @@
     <button onclick="keycloak.register()">Register</button>
     <button onclick="refreshToken(9999)">Refresh Token</button>
     <button onclick="refreshToken(30)">Refresh Token (if <30s validity)</button>
+    <button onclick="refreshToken(5)">Refresh Token (if <5s validity)</button>
     <button onclick="showError()">Show Error Response</button>
     <button onclick="loadProfile()">Get Profile</button>
     <button onclick="loadUserInfo()">Get User Info</button>
@@ -41,6 +42,13 @@
     <button onclick="output(keycloak.createLogoutUrl())">Show Logout URL</button>
     <button onclick="output(keycloak.createRegisterUrl())">Show Register URL</button>
     <button onclick="createBearerRequest()">Create Bearer Request</button>
+    <button onclick="output(showTime())">Show current time</button>
+    <input id="timeSkewInput"/>
+    <button onclick="addToTimeSkew()">timeSkew offset</button>
+    <button onclick="refreshTimeSkew()">refresh timeSkew</button>
+    <button onclick="sendBearerToKeycloak()">Bearer to keycloak</button>
+
+
     <select id="flowSelect">
         <option value="standard">standard</option>
         <option value="implicit">implicit</option>
@@ -62,6 +70,9 @@
 <h2>Events</h2>
 <pre style="background-color: #ddd; border: 1px solid #ccc; padding: 10px;" id="events"></pre>
 
+<h2>Info</h2>
+TimeSkew: <div id="timeSkew"></div>
+
 
 <script>
     function loadProfile() {
@@ -135,6 +146,16 @@
         document.getElementById('events').innerHTML = new Date().toLocaleString() + "\t" + event + "\n" + e;
     }
 
+    function addToTimeSkew() {
+        var offset = document.getElementById("timeSkewInput").value;
+        keycloak.timeSkew += parseInt(offset);
+        document.getElementById("timeSkew").innerHTML = keycloak.timeSkew;
+    }
+
+    function refreshTimeSkew() {
+        document.getElementById("timeSkew").innerHTML = keycloak.timeSkew;
+    }
+
     function createBearerRequest() {
 
         var url = 'http://localhost:8280/js-database/customers';
@@ -167,6 +188,33 @@
         req.send();
     }
 
+    function sendBearerToKeycloak() {
+        var url = 'http://localhost:8180/auth/admin/realms/example/roles';
+        if (window.location.href.indexOf("8543") > -1) {
+            url = url.replace("8180","8543");
+            url = url.replace("http","https");
+        }
+
+        var req = new XMLHttpRequest();
+        req.open('GET', url, true);
+        req.setRequestHeader('Accept', 'application/json');
+        req.setRequestHeader('Authorization', 'Bearer ' + keycloak.token);
+
+        req.onreadystatechange = function () {
+            if (req.readyState == 4) {
+                if (req.status == 200) {
+                    output('Success');
+                } else if (req.status == 403) {
+                    output('Forbidden');
+                } else if (req.status == 401) {
+                    output('Unauthorized');
+                }
+            }
+        };
+
+        req.send();
+    }
+
     var keycloak;
 
     function keycloakInit() {
@@ -182,6 +230,7 @@
 
         keycloak.onAuthRefreshSuccess = function () {
             event('Auth Refresh Success');
+            document.getElementById("timeSkew").innerHTML = keycloak.timeSkew;
         };
 
         keycloak.onAuthRefreshError = function () {
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/JSConsoleTestApp.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/JSConsoleTestApp.java
index 2a57739..4822c4b 100755
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/JSConsoleTestApp.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/JSConsoleTestApp.java
@@ -56,6 +56,8 @@ public class JSConsoleTestApp extends AbstractPageWithInjectedUrl {
     private WebElement refreshTokenButton;
     @FindBy(xpath = "//button[contains(text(),'Refresh Token (if <30s')]")
     private WebElement refreshTokenIfUnder30sButton;
+    @FindBy(xpath = "//button[contains(text(),'Refresh Token (if <5s')]")
+    private WebElement refreshTokenIfUnder5sButton;
     @FindBy(xpath = "//button[text() = 'Get Profile']")
     private WebElement getProfileButton;
 
@@ -73,6 +75,17 @@ public class JSConsoleTestApp extends AbstractPageWithInjectedUrl {
     private WebElement showDetailsButton;
     @FindBy(xpath = "//button[text() = 'Create Bearer Request']")
     private WebElement createBearerRequest;
+    @FindBy(xpath = "//button[text() = 'Bearer to keycloak']")
+    private WebElement createBearerRequestToKeycloakButton;
+    @FindBy(xpath = "//button[text() = 'refresh timeSkew']")
+    private WebElement refreshTimeSkewButton;
+
+    @FindBy(id = "timeSkew")
+    private WebElement timeSkewValue;
+    @FindBy(id = "timeSkewInput")
+    private WebElement timeSkewInput;
+    @FindBy(xpath = "//button[text() = 'timeSkew offset']")
+    private WebElement timeSkewButton;
 
     @FindBy(id = "flowSelect")
     private Select flowSelect;
@@ -104,6 +117,10 @@ public class JSConsoleTestApp extends AbstractPageWithInjectedUrl {
         refreshTokenIfUnder30sButton.click();
     }
 
+    public void refreshTokenIfUnder5s() {
+        refreshTokenIfUnder5sButton.click();
+    }
+
     public void getProfile() {
         getProfileButton.click();
     }
@@ -124,6 +141,10 @@ public class JSConsoleTestApp extends AbstractPageWithInjectedUrl {
         createBearerRequest.click();
     }
 
+    public void createBearerRequestToKeycloak() {
+        createBearerRequestToKeycloakButton.click();
+    }
+
     public void setResponseMode(String value) {
         responseModeSelect.selectByValue(value);
     }
@@ -143,4 +164,18 @@ public class JSConsoleTestApp extends AbstractPageWithInjectedUrl {
     public void showErrorResponse() {
         showErrorButton.click();
     }
+
+    public WebElement getTimeSkewValue() {
+        return timeSkewValue;
+    }
+
+    public void setTimeSkewOffset(int value) {
+        timeSkewInput.clear();
+        timeSkewInput.sendKeys(Integer.toString(value));
+        timeSkewButton.click();
+    }
+
+    public void refreshTimeSkew() {
+        refreshTimeSkewButton.click();
+    }
 }
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/AbstractJSConsoleExampleAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/AbstractJSConsoleExampleAdapterTest.java
index a91b26b..481f022 100755
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/AbstractJSConsoleExampleAdapterTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/AbstractJSConsoleExampleAdapterTest.java
@@ -66,6 +66,8 @@ public abstract class AbstractJSConsoleExampleAdapterTest extends AbstractExampl
     @Page
     private Applications applicationsPage;
 
+    private static int TIME_SKEW_TOLERANCE = 3;
+
     public static int TOKEN_LIFESPAN_LEEWAY = 3; // seconds
 
     @Deployment(name = JSConsoleTestApp.DEPLOYMENT_NAME)
@@ -351,6 +353,42 @@ public abstract class AbstractJSConsoleExampleAdapterTest extends AbstractExampl
         waitUntilElement(jsConsoleTestAppPage.getOutputElement()).text().contains("Init Success (Authenticated)");
     }
 
+    @Test
+    public void testUpdateToken() {
+        logInAndInit("standard");
+
+        jsConsoleTestAppPage.setTimeSkewOffset(-33);
+        setTimeOffset(33);
+
+        jsConsoleTestAppPage.refreshTokenIfUnder5s();
+
+        jsConsoleTestAppPage.setTimeSkewOffset(-34);
+        setTimeOffset(67);
+
+        jsConsoleTestAppPage.refreshTokenIfUnder5s();
+        jsConsoleTestAppPage.createBearerRequestToKeycloak();
+        waitUntilElement(jsConsoleTestAppPage.getOutputElement()).text().contains("Success");
+    }
+
+    @Test
+    public void timeSkewTest() {
+        logInAndInit("standard");
+
+        jsConsoleTestAppPage.refreshTimeSkew();
+
+        int timeSkew = Integer.parseInt(jsConsoleTestAppPage.getTimeSkewValue().getText());
+        assertTrue("TimeSkew was: " + timeSkew + ", but should be ~0", timeSkew >= 0 - TIME_SKEW_TOLERANCE);
+        assertTrue("TimeSkew was: " + timeSkew + ", but should be ~0", timeSkew  <= TIME_SKEW_TOLERANCE);
+
+        setTimeOffset(40);
+        jsConsoleTestAppPage.refreshToken();
+        jsConsoleTestAppPage.refreshTimeSkew();
+
+        timeSkew = Integer.parseInt(jsConsoleTestAppPage.getTimeSkewValue().getText());
+        assertTrue("TimeSkew was: " + timeSkew + ", but should be ~-40", timeSkew + 40 >= 0 - TIME_SKEW_TOLERANCE);
+        assertTrue("TimeSkew was: " + timeSkew + ", but should be ~-40", timeSkew + 40  <= TIME_SKEW_TOLERANCE);
+    }
+
     private void setImplicitFlowForClient() {
         ClientResource clientResource = ApiUtil.findClientResourceByClientId(testRealmResource(), "js-console");
         ClientRepresentation client = clientResource.toRepresentation();