keycloak-uncached

Details

diff --git a/services/src/main/java/org/keycloak/services/resources/account/AccountConsole.java b/services/src/main/java/org/keycloak/services/resources/account/AccountConsole.java
index 4eed994..43ddc4a 100644
--- a/services/src/main/java/org/keycloak/services/resources/account/AccountConsole.java
+++ b/services/src/main/java/org/keycloak/services/resources/account/AccountConsole.java
@@ -32,6 +32,9 @@ import javax.json.Json;
 import javax.json.JsonObjectBuilder;
 import javax.json.JsonWriter;
 import org.jboss.logging.Logger;
+import org.keycloak.common.Profile;
+import org.keycloak.events.EventStoreProvider;
+import org.keycloak.forms.account.freemarker.model.FeaturesBean;
 import org.keycloak.models.ClientModel;
 import org.keycloak.protocol.oidc.utils.RedirectUtils;
 import org.keycloak.services.managers.RealmManager;
@@ -108,6 +111,10 @@ public class AccountConsole {
             map.put("msgJSON", messagesToJsonString(messages));
             map.put("supportedLocales", supportedLocales(messages));
             map.put("properties", theme.getProperties());
+            
+            EventStoreProvider eventStore = session.getProvider(EventStoreProvider.class);
+            map.put("isEventsEnabled", eventStore != null && realm.isEventsEnabled());
+            map.put("isAuthorizationEnabled", Profile.isFeatureEnabled(Profile.Feature.AUTHORIZATION));
 
             FreeMarkerUtil freeMarkerUtil = new FreeMarkerUtil();
             String result = freeMarkerUtil.processTemplate(map, "index.ftl", theme);
diff --git a/themes/src/main/resources/theme/keycloak-preview/account/index.ftl b/themes/src/main/resources/theme/keycloak-preview/account/index.ftl
index d7495ce..a191417 100644
--- a/themes/src/main/resources/theme/keycloak-preview/account/index.ftl
+++ b/themes/src/main/resources/theme/keycloak-preview/account/index.ftl
@@ -13,10 +13,16 @@
             var baseUrl = '${baseUrl}';
             var realm = '${realm.name}';
             var resourceUrl = '${resourceUrl}';
-            var isRegistrationEmailAsUsername = ${realm.registrationEmailAsUsername?c};
-            var isEditUserNameAllowed = ${realm.editUsernameAllowed?c};
-            var isInternationalizationEnabled = ${realm.internationalizationEnabled?c};
-
+                
+            var features = {
+                isRegistrationEmailAsUsername : ${realm.registrationEmailAsUsername?c},
+                isEditUserNameAllowed : ${realm.editUsernameAllowed?c},
+                isInternationalizationEnabled : ${realm.internationalizationEnabled?c},
+                isLinkedAccountsEnabled : ${realm.identityFederationEnabled?c},
+                isEventsEnabled : ${isEventsEnabled?c},
+                isMyResourcesEnabled : ${(realm.userManagedAccessAllowed && isAuthorizationEnabled)?c}
+            }
+                
             var availableLocales = [];
             <#list supportedLocales as locale, label>
                 availableLocales.push({locale : '${locale}', label : '${label}'});
@@ -190,7 +196,7 @@
                               <h3><a href="${baseUrl}/#/password">${msg("changePasswordHtmlTitle")}</a></h3>
                               <h3><a href="${baseUrl}/#/authenticator">${msg("authenticatorTitle")}</a></h3>
                               <h3><a href="${baseUrl}/#/device-activity">${msg("deviceActivityHtmlTitle")}</a></h3>
-                              <h3><a href="${baseUrl}/#/linked-accounts">${msg("linkedAccountsHtmlTitle")}</a></h3>
+                              <h3 id="linkedAccounts"><a href="${baseUrl}/#/linked-accounts">${msg("linkedAccountsHtmlTitle")}</a></h3>
                             </div>
                         </div>
                     </div>
@@ -209,7 +215,7 @@
                         </div>
                     </div>
                 </div>
-                <div class="col-xs-12 col-sm-4 col-md-4 col-lg-3">
+                <div id="myResources" class="col-xs-12 col-sm-4 col-md-4 col-lg-3">
                     <div class="card-pf card-pf-view card-pf-view-select card-pf-view-single-select">
                         <div class="card-pf-body text-center row">
                             <div class="card-pf-top-element col-xs-2 col-sm-12 col-md-12 col-lg-12">
@@ -229,6 +235,14 @@
     </div>
 
         <script>
+            if (!features.isLinkedAccountsEnabled) {
+                document.getElementById("linkedAccounts").style.display='none';
+            }
+                
+            if (!features.isMyResourcesEnabled) {
+                document.getElementById("myResources").style.display='none';
+            }
+                
             var winHash = window.location.hash;
             if ((winHash.indexOf('#/') == 0) && (!winHash.indexOf('#/&state') == 0)) {
                 document.getElementById("welcomeScreen").style.display='none';
diff --git a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/account-page/account-page.component.ts b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/account-page/account-page.component.ts
index ab51ab6..eaeb193 100644
--- a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/account-page/account-page.component.ts
+++ b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/account-page/account-page.component.ts
@@ -18,10 +18,10 @@ import {Component, OnInit, ViewChild} from '@angular/core';
 import {Response} from '@angular/http';
 import {FormGroup} from '@angular/forms';
 
+import {Features} from '../../page/features';
 import {AccountServiceClient} from '../../account-service/account.service';
 
-declare const isRegistrationEmailAsUsername: boolean;
-declare const isEditUserNameAllowed: boolean;
+declare const features: Features;
 
 @Component({
     selector: 'app-account-page',
@@ -29,8 +29,8 @@ declare const isEditUserNameAllowed: boolean;
     styleUrls: ['./account-page.component.css']
 })
 export class AccountPageComponent implements OnInit {
-    private isRegistrationEmailAsUsername: boolean = isRegistrationEmailAsUsername;
-    private isEditUserNameAllowed: boolean = isEditUserNameAllowed;
+    private isRegistrationEmailAsUsername: boolean = features.isRegistrationEmailAsUsername;
+    private isEditUserNameAllowed: boolean = features.isEditUserNameAllowed;
     
     @ViewChild('formGroup') private formGroup: FormGroup;
     
diff --git a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/top-nav/top-nav.component.ts b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/top-nav/top-nav.component.ts
index fa49a26..4458aa3 100644
--- a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/top-nav/top-nav.component.ts
+++ b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/top-nav/top-nav.component.ts
@@ -18,13 +18,14 @@ import {Component, OnInit, Input} from '@angular/core';
 import {TranslateUtil} from '../ngx-translate/translate.util';
 import {KeycloakService} from '../keycloak-service/keycloak.service';
 import {ResponsivenessService} from "../responsiveness-service/responsiveness.service";
+import {Features} from '../page/features';
 import {Referrer} from "../page/referrer";
 
 declare const resourceUrl: string;
 declare const baseUrl: string;
 declare const referrer: string;
 declare const referrer_uri: string;
-declare const isInternationalizationEnabled: boolean;
+declare const features: Features;
 declare const availableLocales: Array<Object>;
 
 @Component({
@@ -58,7 +59,7 @@ export class TopNavComponent implements OnInit {
     }
     
     private showLocales(): boolean {
-        return isInternationalizationEnabled && (this.availableLocales.length > 1); 
+        return features.isInternationalizationEnabled && (this.availableLocales.length > 1); 
     }
     
     private changeLocale(newLocale: string) {
diff --git a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/vertical-nav/vertical-nav.component.ts b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/vertical-nav/vertical-nav.component.ts
index bbcbe62..3ff0d5b 100644
--- a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/vertical-nav/vertical-nav.component.ts
+++ b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/vertical-nav/vertical-nav.component.ts
@@ -2,11 +2,12 @@ import {Component, OnInit, ViewEncapsulation, ViewChild} from '@angular/core';
 import {NavigationItemConfig, VerticalNavigationComponent} from 'patternfly-ng/navigation';
 import {TranslateUtil} from '../ngx-translate/translate.util';
 import {KeycloakService} from '../keycloak-service/keycloak.service';
+import {Features} from '../page/features';
 import {Referrer} from "../page/referrer";
 
 declare const baseUrl: string;
 declare const resourceUrl: string;
-declare const isInternationalizationEnabled: boolean;
+declare const features: Features;
 declare const availableLocales: Array<Object>;
 
 @Component({
@@ -26,7 +27,7 @@ export class VerticalNavComponent implements OnInit {
     navigationItems: NavigationItemConfig[];
 
     constructor(private keycloakService: KeycloakService,
-                private translateUtil: TranslateUtil, ) {
+        private translateUtil: TranslateUtil, ) {
         this.referrer = new Referrer(translateUtil);
     }
 
@@ -41,40 +42,54 @@ export class VerticalNavComponent implements OnInit {
             {
                 title: this.translateUtil.translate('accountSecurityTitle'),
                 iconStyleClass: 'fa fa-shield',
-                children: [
-                    {
-                        title: this.translateUtil.translate('changePasswordHtmlTitle'),
-                        iconStyleClass: 'fa fa-shield',
-                        url: 'password',
-                    },
-                    {
-                        title: this.translateUtil.translate('authenticatorTitle'),
-                        iconStyleClass: 'fa fa-shield',
-                        url: 'authenticator',
-                    },
-                    {
-                        title: this.translateUtil.translate('device-activity'),
-                        iconStyleClass: 'fa fa-shield',
-                        url: 'device-activity',
-                    },
-                    {
-                        title: this.translateUtil.translate('linkedAccountsHtmlTitle'),
-                        iconStyleClass: 'fa fa-shield',
-                        url: 'linked-accounts',
-                    },
-                ],
+                children: this.makeSecurityChildren(),
             },
             {
                 title: this.translateUtil.translate('applicationsHtmlTitle'),
                 iconStyleClass: 'fa fa-th',
                 url: 'applications',
+            }
+        ];
+
+        if (features.isMyResourcesEnabled) {
+            this.navigationItems.push(
+                {
+                    title: this.translateUtil.translate('myResources'),
+                    iconStyleClass: 'fa fa-file-o',
+                    url: 'my-resources',
+                }
+            );
+        }
+    }
+
+    private makeSecurityChildren(): Array<NavigationItemConfig> {
+        const children: Array<NavigationItemConfig> = [
+            {
+                title: this.translateUtil.translate('changePasswordHtmlTitle'),
+                iconStyleClass: 'fa fa-shield',
+                url: 'password',
             },
             {
-                title: this.translateUtil.translate('myResources'),
-                iconStyleClass: 'fa fa-file-o',
-                url: 'my-resources',
+                title: this.translateUtil.translate('authenticatorTitle'),
+                iconStyleClass: 'fa fa-shield',
+                url: 'authenticator',
+            },
+            {
+                title: this.translateUtil.translate('device-activity'),
+                iconStyleClass: 'fa fa-shield',
+                url: 'device-activity',
             }
         ];
+
+        if (features.isLinkedAccountsEnabled) {
+            children.push({
+                title: this.translateUtil.translate('linkedAccountsHtmlTitle'),
+                iconStyleClass: 'fa fa-shield',
+                url: 'linked-accounts',
+            });
+        };
+
+        return children;
     }
 
     private logout() {
@@ -82,7 +97,7 @@ export class VerticalNavComponent implements OnInit {
     }
 
     private isShowLocales(): boolean {
-        return isInternationalizationEnabled && (this.availableLocales.length > 1);
+        return features.isInternationalizationEnabled && (this.availableLocales.length > 1);
     }
 
     private changeLocale(newLocale: string) {