keycloak-aplcache

Fixes to account referrer to allow configurable referrer uri

3/19/2014 1:32:51 PM

Details

diff --git a/examples/cordova/www/index.html b/examples/cordova/www/index.html
index 43bd527..27d7db1 100644
--- a/examples/cordova/www/index.html
+++ b/examples/cordova/www/index.html
@@ -42,6 +42,7 @@
     <div>
         <button onclick="keycloak.logout()">Log out</button>
         <button onclick="keycloak.updateToken()">Refresh token</button>
+        <button onclick="keycloak.accountManagement()">Manage account</button>
     </div>
     <div>
         <table>
diff --git a/forms/account-api/src/main/java/org/keycloak/account/Account.java b/forms/account-api/src/main/java/org/keycloak/account/Account.java
index 61e92e2..060b8a5 100644
--- a/forms/account-api/src/main/java/org/keycloak/account/Account.java
+++ b/forms/account-api/src/main/java/org/keycloak/account/Account.java
@@ -25,6 +25,6 @@ public interface Account {
 
     public Account setRealm(RealmModel realm);
 
-    public Account setReferrer(String referrer);
+    public Account setReferrer(String[] referrer);
 
 }
diff --git a/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/FreeMarkerAccount.java b/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/FreeMarkerAccount.java
index 1a5cc67..143aa1c 100644
--- a/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/FreeMarkerAccount.java
+++ b/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/FreeMarkerAccount.java
@@ -36,7 +36,7 @@ public class FreeMarkerAccount implements Account {
     private UserModel user;
     private Response.Status status = Response.Status.OK;
     private RealmModel realm;
-    private String referrer;
+    private String[] referrer;
 
     public static enum MessageType {SUCCESS, WARNING, ERROR}
 
@@ -82,9 +82,8 @@ public class FreeMarkerAccount implements Account {
             attributes.put("message", new MessageBean(messages.containsKey(message) ? messages.getProperty(message) : message, messageType));
         }
 
-        ApplicationModel referrerApp = getReferrer();
-        if (referrerApp != null) {
-            attributes.put("referrer", new ReferrerBean(referrerApp));
+        if (referrer != null) {
+            attributes.put("referrer", new ReferrerBean(referrer));
         }
 
         attributes.put("url", new UrlBean(realm, theme, baseUri));
@@ -114,16 +113,6 @@ public class FreeMarkerAccount implements Account {
         }
     }
 
-    private ApplicationModel getReferrer() {
-        if (referrer != null) {
-            ApplicationModel app = realm.getApplicationByName(referrer);
-            if (app != null) {
-                return app;
-            }
-        }
-        return null;
-    }
-
     @Override
     public Account setError(String message) {
         this.message = message;
@@ -164,7 +153,7 @@ public class FreeMarkerAccount implements Account {
     }
 
     @Override
-    public Account setReferrer(String referrer) {
+    public Account setReferrer(String[] referrer) {
         this.referrer = referrer;
         return this;
     }
diff --git a/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/model/ReferrerBean.java b/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/model/ReferrerBean.java
index 8904bf6..0734a7b 100644
--- a/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/model/ReferrerBean.java
+++ b/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/model/ReferrerBean.java
@@ -1,24 +1,22 @@
 package org.keycloak.account.freemarker.model;
 
-import org.keycloak.models.ApplicationModel;
-
 /**
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
  */
 public class ReferrerBean {
 
-    private ApplicationModel referrer;
+    private String[] referrer;
 
-    public ReferrerBean(ApplicationModel referrer) {
+    public ReferrerBean(String[] referrer) {
         this.referrer = referrer;
     }
 
     public String getName() {
-        return referrer.getName();
+        return referrer[0];
     }
 
-    public String getBaseUrl() {
-        return referrer.getBaseUrl();
+    public String getUrl() {
+        return referrer[1];
     }
 
 }
diff --git a/forms/common-themes/src/main/resources/theme/account/base/template.ftl b/forms/common-themes/src/main/resources/theme/account/base/template.ftl
index 376a421..d6a2f5e 100644
--- a/forms/common-themes/src/main/resources/theme/account/base/template.ftl
+++ b/forms/common-themes/src/main/resources/theme/account/base/template.ftl
@@ -28,7 +28,7 @@
             <div class="navbar-collapse navbar-collapse-1">
                 <div class="container">
                     <ul class="nav navbar-nav navbar-utility">
-                        <#if referrer?has_content && referrer.baseUrl?has_content><li><a href="${referrer.baseUrl}">Back to ${referrer.name}</a></li></#if>
+                        <#if referrer?has_content && referrer.url?has_content><li><a href="${referrer.url}" id="referrer">Back to ${referrer.name}</a></li></#if>
                         <li><a href="${url.logoutUrl}">Sign Out</a></li>
                     </ul>
                 </div>
diff --git a/integration/js/src/main/resources/META-INF/resources/js/keycloak.js b/integration/js/src/main/resources/META-INF/resources/js/keycloak.js
index 821d0e1..11da6c8 100755
--- a/integration/js/src/main/resources/META-INF/resources/js/keycloak.js
+++ b/integration/js/src/main/resources/META-INF/resources/js/keycloak.js
@@ -103,10 +103,11 @@ var Keycloak = function (config) {
         return url;
     }
 
-    kc.createAccountUrl = function() {
+    kc.createAccountUrl = function(options) {
         var url = getRealmUrl()
             + '/account'
-            + '?referrer=' + kc.clientId;
+            + '?referrer=' + kc.clientId
+            + '&referrer_uri=' + encodeURIComponent(adapter.redirectUri(options));
 
         return url;
     }
diff --git a/services/src/main/java/org/keycloak/services/resources/AccountService.java b/services/src/main/java/org/keycloak/services/resources/AccountService.java
index 593f3d3..eb53402 100755
--- a/services/src/main/java/org/keycloak/services/resources/AccountService.java
+++ b/services/src/main/java/org/keycloak/services/resources/AccountService.java
@@ -99,7 +99,7 @@ public class AccountService {
 
             Account account = AccountLoader.load().createAccount(uriInfo).setRealm(realm).setUser(auth.getUser());
 
-            String referrer = getReferrer();
+            String[] referrer = getReferrer();
             if (referrer != null) {
                 account.setReferrer(referrer);
             }
@@ -377,13 +377,17 @@ public class AccountService {
             uriBuilder.queryParam("path", path);
         }
 
-        String referrer = getReferrer();
+        String referrer = uriInfo.getQueryParameters().getFirst("referrer");
         if (referrer != null) {
             uriBuilder.queryParam("referrer", referrer);
         }
 
-        URI accountUri = uriBuilder.build(realm.getName());
+        String referrerUri = uriInfo.getQueryParameters().getFirst("referrer_uri");
+        if (referrerUri != null) {
+            uriBuilder.queryParam("referrer_uri", referrerUri);
+        }
 
+        URI accountUri = uriBuilder.build(realm.getName());
 
         oauth.setStateCookiePath(accountUri.getRawPath());
         return oauth.redirect(uriInfo, accountUri.toString());
@@ -397,20 +401,34 @@ public class AccountService {
         return auth;
     }
 
-    private String getReferrer() {
+    private String[] getReferrer() {
         String referrer = uriInfo.getQueryParameters().getFirst("referrer");
-        if (referrer != null) {
-            return referrer;
+        if (referrer == null) {
+            return null;
         }
 
-        String referrerUrl = headers.getHeaderString("Referer");
-        if (referrerUrl != null) {
-            for (ApplicationModel a : realm.getApplications()) {
-                if (a.getBaseUrl() != null && referrerUrl.startsWith(a.getBaseUrl())) {
-                    return a.getName();
+        String referrerUri = uriInfo.getQueryParameters().getFirst("referrer_uri");
+
+        ApplicationModel application = realm.getApplicationByName(referrer);
+        if (application != null) {
+            if (referrerUri != null) {
+                referrerUri = TokenService.verifyRedirectUri(referrerUri, application);
+            } else {
+                referrerUri = application.getBaseUrl();
+            }
+
+            if (referrerUri != null) {
+                return new String[] { referrer, referrerUri };
+            }
+        } else if (referrerUri != null) {
+            ClientModel client = realm.getOAuthClient(referrer);
+            if (client != null) {
+                referrerUri = TokenService.verifyRedirectUri(referrerUri, application);
+
+                if (referrerUri != null) {
+                    return new String[] { referrer, referrerUri };
                 }
             }
-            return null;
         }
 
         return null;
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/AccountTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/AccountTest.java
index 0aa9075..27e013b 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/AccountTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/AccountTest.java
@@ -107,26 +107,21 @@ public class AccountTest {
         });
     }
 
-    //@Test
-    public void returnToAppFromHeader() {
-        appPage.open();
-        appPage.openAccount();
+    @Test
+    public void returnToAppFromQueryParam() {
+        driver.navigate().to(AccountUpdateProfilePage.PATH + "?referrer=test-app");
         loginPage.login("test-user@localhost", "password");
-
         Assert.assertTrue(profilePage.isCurrent());
         profilePage.backToApplication();
 
         Assert.assertTrue(appPage.isCurrent());
-    }
 
-    //@Test
-    public void returnToAppFromQueryParam() {
-        driver.navigate().to(AccountUpdateProfilePage.PATH + "?referrer=test-app");
-        loginPage.login("test-user@localhost", "password");
+        driver.navigate().to(AccountUpdateProfilePage.PATH + "?referrer=test-app&referrer_uri=http://localhost:8081/app?test");
         Assert.assertTrue(profilePage.isCurrent());
         profilePage.backToApplication();
 
         Assert.assertTrue(appPage.isCurrent());
+        Assert.assertEquals(appPage.baseUrl + "?test", driver.getCurrentUrl());
     }
 
     @Test
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/AccountUpdateProfilePage.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/AccountUpdateProfilePage.java
index 3f9c784..582c112 100644
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/AccountUpdateProfilePage.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/AccountUpdateProfilePage.java
@@ -42,7 +42,7 @@ public class AccountUpdateProfilePage extends AbstractAccountPage {
     private WebElement emailInput;
 
 
-    @FindBy(linkText = "Back to application")
+    @FindBy(id = "referrer")
     private WebElement backToApplicationLink;
 
     @FindBy(css = "button[type=\"submit\"]")
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/AppPage.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/AppPage.java
index c0ce139..7fa6c9e 100644
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/AppPage.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/AppPage.java
@@ -30,7 +30,7 @@ import org.openqa.selenium.support.FindBy;
  */
 public class AppPage extends AbstractPage {
 
-    private String baseUrl = "http://localhost:8081/app";
+    public static final String baseUrl = "http://localhost:8081/app";
 
     @FindBy(id = "account")
     private WebElement accountLink;