keycloak-aplcache

KEYCLOAK-4234: Link to app in acct mgt doesn't use root url (#4285) *

7/4/2017 2:01:58 AM

Details

diff --git a/services/src/main/java/org/keycloak/forms/account/freemarker/model/ApplicationsBean.java b/services/src/main/java/org/keycloak/forms/account/freemarker/model/ApplicationsBean.java
index de5fd93..e3611f7 100755
--- a/services/src/main/java/org/keycloak/forms/account/freemarker/model/ApplicationsBean.java
+++ b/services/src/main/java/org/keycloak/forms/account/freemarker/model/ApplicationsBean.java
@@ -140,7 +140,48 @@ public class ApplicationsBean {
         public MultivaluedHashMap<String, ClientRoleEntry> getResourceRolesGranted() {
             return resourceRolesGranted;
         }
-
+        
+        public String getEffectiveUrl() {
+            String rootUrl = getClient().getRootUrl();
+            String baseUrl = getClient().getBaseUrl();
+            
+            if (rootUrl == null) rootUrl = "";
+            if (baseUrl == null) baseUrl = "";
+            
+            if (rootUrl.equals("") && baseUrl.equals("")) {
+                return "";
+            }
+            
+            if (rootUrl.equals("") && !baseUrl.equals("")) {
+                return baseUrl;
+            }
+            
+            if (!rootUrl.equals("") && baseUrl.equals("")) {
+                return rootUrl;
+            }
+            
+            if (isBaseUrlRelative() && !rootUrl.equals("")) {
+                return concatUrls(rootUrl, baseUrl);
+            }
+            
+            return baseUrl;
+        }
+        
+        private String concatUrls(String u1, String u2) {
+            if (u1.endsWith("/")) u1 = u1.substring(0, u1.length() - 1);
+            if (u2.startsWith("/")) u2 = u2.substring(1);
+            return u1 + "/" + u2;
+        }
+        
+        private boolean isBaseUrlRelative() {
+            String baseUrl = getClient().getBaseUrl();
+            if (baseUrl.equals("")) return false;
+            if (baseUrl.startsWith("/")) return true;
+            if (baseUrl.startsWith("./")) return true;
+            if (baseUrl.startsWith("../")) return true;
+            return false;
+        }
+        
         public ClientModel getClient() {
             return client;
         }
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/pages/AccountApplicationsPage.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/pages/AccountApplicationsPage.java
index 11aac0b..8c647cc 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/pages/AccountApplicationsPage.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/pages/AccountApplicationsPage.java
@@ -61,6 +61,14 @@ public class AccountApplicationsPage extends AbstractAccountPage {
                     case 1:
                         currentEntry = new AppEntry();
                         String client = col.getText();
+                        WebElement link = null;
+                        try {
+                            link = col.findElement(By.tagName("a"));
+                            String href = link.getAttribute("href");
+                            currentEntry.setHref(href);
+                        } catch (Exception e) {
+                            //ignore
+                        }
                         table.put(client, currentEntry);
                         break;
                     case 2:
@@ -111,6 +119,7 @@ public class AccountApplicationsPage extends AbstractAccountPage {
         private final List<String> rolesGranted = new ArrayList<String>();
         private final List<String> protocolMappersGranted = new ArrayList<String>();
         private final List<String> additionalGrants = new ArrayList<>();
+        private String href = null;
 
         private void addAvailableRole(String role) {
             rolesAvailable.add(role);
@@ -127,6 +136,14 @@ public class AccountApplicationsPage extends AbstractAccountPage {
         private void addAdditionalGrant(String grant) {
             additionalGrants.add(grant);
         }
+        
+        public void setHref(String href) {
+            this.href = href;
+        }
+        
+        public String getHref() {
+            return this.href;
+        }
 
         public List<String> getRolesGranted() {
             return rolesGranted;
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/AccountTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/AccountTest.java
index eba81f4..9dad375 100755
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/AccountTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/AccountTest.java
@@ -880,7 +880,7 @@ public class AccountTest extends AbstractTestRealmKeycloakTest {
         Assert.assertTrue(applicationsPage.isCurrent());
 
         Map<String, AccountApplicationsPage.AppEntry> apps = applicationsPage.getApplications();
-        Assert.assertThat(apps.keySet(), containsInAnyOrder("Account", "test-app", "test-app-scope", "third-party", "test-app-authz", "My Named Test App", "Test App Named - ${client_account}"));
+        Assert.assertThat(apps.keySet(), containsInAnyOrder("root-url-client", "Account", "test-app", "test-app-scope", "third-party", "test-app-authz", "My Named Test App", "Test App Named - ${client_account}"));
 
         AccountApplicationsPage.AppEntry accountEntry = apps.get("Account");
         Assert.assertEquals(3, accountEntry.getRolesAvailable().size());
@@ -891,12 +891,14 @@ public class AccountTest extends AbstractTestRealmKeycloakTest {
         Assert.assertTrue(accountEntry.getRolesGranted().contains("Full Access"));
         Assert.assertEquals(1, accountEntry.getProtocolMappersGranted().size());
         Assert.assertTrue(accountEntry.getProtocolMappersGranted().contains("Full Access"));
+        Assert.assertEquals("http://localhost:8180/auth/realms/test/account", accountEntry.getHref());
 
         AccountApplicationsPage.AppEntry testAppEntry = apps.get("test-app");
         Assert.assertEquals(5, testAppEntry.getRolesAvailable().size());
         Assert.assertTrue(testAppEntry.getRolesAvailable().contains("Offline access"));
         Assert.assertTrue(testAppEntry.getRolesGranted().contains("Full Access"));
         Assert.assertTrue(testAppEntry.getProtocolMappersGranted().contains("Full Access"));
+        Assert.assertEquals("http://localhost:8180/auth/realms/master/app/auth", testAppEntry.getHref());
 
         AccountApplicationsPage.AppEntry thirdPartyEntry = apps.get("third-party");
         Assert.assertEquals(2, thirdPartyEntry.getRolesAvailable().size());
@@ -904,6 +906,22 @@ public class AccountTest extends AbstractTestRealmKeycloakTest {
         Assert.assertTrue(thirdPartyEntry.getRolesAvailable().contains("Have Customer User privileges in test-app"));
         Assert.assertEquals(0, thirdPartyEntry.getRolesGranted().size());
         Assert.assertEquals(0, thirdPartyEntry.getProtocolMappersGranted().size());
+        Assert.assertEquals("http://localhost:8180/auth/realms/master/app/auth", thirdPartyEntry.getHref());
+        
+        AccountApplicationsPage.AppEntry testAppNamed = apps.get("Test App Named - ${client_account}");
+        Assert.assertEquals("http://localhost:8180/varnamedapp/base", testAppNamed.getHref());
+        
+        AccountApplicationsPage.AppEntry rootUrlClient = apps.get("root-url-client");
+        Assert.assertEquals("http://localhost:8180/foo/bar/baz", rootUrlClient.getHref());
+        
+        AccountApplicationsPage.AppEntry authzApp = apps.get("test-app-authz");
+        Assert.assertEquals("http://localhost:8180/test-app-authz", authzApp.getHref());
+        
+        AccountApplicationsPage.AppEntry namedApp = apps.get("My Named Test App");
+        Assert.assertEquals("http://localhost:8180/namedapp/base", namedApp.getHref());
+        
+        AccountApplicationsPage.AppEntry testAppScope = apps.get("test-app-scope");
+        Assert.assertNull(testAppScope.getHref());
     }
 
     @Test
diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/testrealm.json b/testsuite/integration-arquillian/tests/base/src/test/resources/testrealm.json
index f4b118e..2ce6b39 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/resources/testrealm.json
+++ b/testsuite/integration-arquillian/tests/base/src/test/resources/testrealm.json
@@ -148,6 +148,17 @@
       "secret": "password"
     },
     {
+      "clientId": "root-url-client",
+      "enabled": true,
+      "rootUrl": "http://localhost:8180/foo/bar",
+      "adminUrl": "http://localhost:8180/foo/bar",
+      "baseUrl": "/baz",
+      "redirectUris": [
+        "http://localhost:8180/foo/bar/*"
+      ],
+      "secret": "password"
+    },
+    {
       "clientId" : "test-app-scope",
       "enabled": true,
 
diff --git a/themes/src/main/resources/theme/base/account/applications.ftl b/themes/src/main/resources/theme/base/account/applications.ftl
index bca5102..45a253a 100755
--- a/themes/src/main/resources/theme/base/account/applications.ftl
+++ b/themes/src/main/resources/theme/base/account/applications.ftl
@@ -27,9 +27,9 @@
               <#list applications.applications as application>
                 <tr>
                     <td>
-                        <#if application.client.baseUrl??><a href="${application.client.baseUrl}"></#if>
+                        <#if application.effectiveUrl?has_content><a href="${application.effectiveUrl}"></#if>
                             <#if application.client.name??>${advancedMsg(application.client.name)}<#else>${application.client.clientId}</#if>
-                        <#if application.client.baseUrl??></a></#if>
+                        <#if application.effectiveUrl?has_content></a></#if>
                     </td>
 
                     <td>