keycloak-uncached

Details

diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/js/app.js b/admin-ui/src/main/resources/META-INF/resources/admin/js/app.js
index cbfea0a..4c8d2c2 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/js/app.js
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/js/app.js
@@ -41,7 +41,7 @@ module.config([ '$routeProvider', function($routeProvider) {
                     return RealmLoader();
                 }
             },
-            controller : 'RealmTokenDetailCtrl'
+            controller : 'RealmSocialCtrl'
         })
         .when('/realms/:realm/required-credentials', {
             templateUrl : 'partials/realm-credentials.html',
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers/realm.js b/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers/realm.js
index 6c83262..2cda1e9 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers/realm.js
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers/realm.js
@@ -196,6 +196,123 @@ module.controller('RealmRequiredCredentialsCtrl', function($scope, Realm, realm,
     };
 });
 
+module.controller('RealmSocialCtrl', function($scope, realm, Realm, $location, Notifications) {
+    console.log('RealmSocialCtrl');
+
+    $scope.realm = { id : realm.id, realm : realm.realm, social : realm.social, tokenLifespan : realm.tokenLifespan,  accessCodeLifespan : realm.accessCodeLifespan };
+
+    if (!realm["socialProviders"]){
+        $scope.realm["socialProviders"] = {};
+    } else {
+        $scope.realm["socialProviders"] = realm.socialProviders;
+    }
+
+    // Hardcoded provider list
+    $scope.availableProviders = [ "google", "facebook", "twitter"];
+
+    var oldCopy = angular.copy($scope.realm);
+    $scope.changed = false;
+    $scope.callbackUrl = "http://mock.url.org/don/t/know/what/to/place/here";
+
+    // To get rid of the "undefined" option in the provider select list
+    // Setting the 1st option from the list (if the list is not empty)
+    var selectFirstProvider = function(){
+        if ($scope.unsetProviders.length > 0){
+            $scope.newProviderId = $scope.unsetProviders[0];
+        } else {
+            $scope.newProviderId = null;
+        }
+    }
+
+    // Fill in configured providers
+    var initSocial = function() {
+        $scope.unsetProviders = [];
+        $scope.configuredProviders = [];
+
+        for (var providerConfig in $scope.realm.socialProviders){
+            // Get the provider ID which is before the '.' (i.e. google in google.key or google.secret)
+            if ($scope.realm.socialProviders.hasOwnProperty(providerConfig)){
+                var pId = providerConfig.split('.')[0];
+                if ($scope.configuredProviders.indexOf(pId) < 0){
+                    $scope.configuredProviders.push(pId);
+                }
+            }
+        }
+
+        // If no providers are already configured, you can add any of them
+        if ($scope.configuredProviders.length == 0){
+            $scope.unsetProviders = $scope.availableProviders;
+        } else {
+            for (var i = 0; i < $scope.availableProviders.length; i++){
+                var providerId = $scope.availableProviders[i];
+                if ($scope.configuredProviders.indexOf(providerId) < 0){
+                    $scope.unsetProviders.push(providerId);
+                }
+            }
+        }
+
+        selectFirstProvider();
+    };
+
+    initSocial();
+
+    $scope.addProvider = function() {
+        if ($scope.availableProviders.indexOf($scope.newProviderId) > -1){
+            $scope.realm.socialProviders[$scope.newProviderId+".key"]="";
+            $scope.realm.socialProviders[$scope.newProviderId+".secret"]="";
+            $scope.configuredProviders.push($scope.newProviderId);
+            $scope.unsetProviders.remove($scope.unsetProviders.indexOf($scope.newProviderId));
+            selectFirstProvider();
+        }
+    };
+
+    $scope.removeProvider = function(pId) {
+        delete $scope.realm.socialProviders[pId+".key"];
+        delete $scope.realm.socialProviders[pId+".secret"];
+        $scope.configuredProviders.remove($scope.configuredProviders.indexOf(pId));
+        $scope.unsetProviders.push(pId);
+    };
+
+    $scope.$watch('realm', function() {
+        if (!angular.equals($scope.realm, oldCopy)) {
+            $scope.changed = true;
+        }
+    }, true);
+
+    $scope.save = function() {
+        $scope.saveClicked = true;
+
+        if ($scope.realmForm.$valid) {
+            var realmCopy = angular.copy($scope.realm);
+            realmCopy.social = true;
+            $scope.changed = false;
+            Realm.update(realmCopy, function () {
+                $location.url("/realms/" + realm.id + "/social-settings");
+                Notifications.success("Saved changes to realm");
+            });
+        } else {
+            $scope.realmForm.showErrors = true;
+            Notifications.error("Some required fields are missing values.");
+        }
+    };
+
+    $scope.reset = function() {
+        $scope.realm = angular.copy(oldCopy);
+        $scope.changed = false;
+        // Initialize lists of configured and unset providers again
+        initSocial();
+    };
+
+    $scope.openHelp = function(pId) {
+        $scope.helpPId = pId;
+        $scope.providerHelpModal = true;
+    };
+
+    $scope.closeHelp = function() {
+        $scope.providerHelpModal = false;
+    };
+
+});
 
 module.controller('RealmTokenDetailCtrl', function($scope, Realm, realm, $http, $location, Dialog, Notifications) {
     console.log('RealmTokenDetailCtrl');
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/provider/facebook-help.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/provider/facebook-help.html
new file mode 100755
index 0000000..b77979d
--- /dev/null
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/provider/facebook-help.html
@@ -0,0 +1,28 @@
+<p>
+    Mock page for <i>Facebook provider help</i>.
+</p>
+
+<p>Fill in name, description and website. For <i>Callback URL</i> use the following value:</p>
+
+<ul>
+    <li><b>Callback URL:</b> {{callbackUrl}}</li>
+</ul>
+
+<form class="form-horizontal" name="fbHelpForm">
+    <div class="control-group">
+        <label class="control-label" for="providerHelp.key">Consumer key </label>
+        <div class="controls">
+            <input type="text" class="input-xlarge" id="providerHelp.key" ng-model="realm.socialProviders[helpPId+'.key']">
+        </div>
+    </div>
+    <div class="control-group">
+        <label class="control-label" for="providerHelp.secret">Consumer secret </label>
+        <div class="controls">
+            <input type="text" class="input-xlarge" id="providerHelp.secret" ng-model="realm.socialProviders[helpPId+'.secret']">
+        </div>
+    </div>
+</form>
+
+<p>
+    Close the help panel and click <i>save changes</i>.
+</p>
\ No newline at end of file
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/provider/google-help.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/provider/google-help.html
index 5a45c6c..1c2eae1 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/provider/google-help.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/provider/google-help.html
@@ -21,20 +21,16 @@
 <form class="form-horizontal" name="googleHelpForm">
     <div class="control-group">
         <label class="control-label" for="providerHelp.key">Client ID </label>
-
         <div class="controls">
-            <input type="text" class="input-xlarge" id="providerHelp.key"
-                   data-ng-model="application.providers[providerHelp.index].key">
+            <input type="text" class="input-xlarge" id="providerHelp.key" ng-model="realm.socialProviders[helpPId+'.key']">
         </div>
     </div>
     <div class="control-group">
         <label class="control-label" for="providerHelp.secret">Client secret </label>
-
         <div class="controls">
-            <input type="text" class="input-xlarge" id="providerHelp.secret"
-                   data-ng-model="application.providers[providerHelp.index].secret">
+            <input type="text" class="input-xlarge" id="providerHelp.secret" ng-model="realm.socialProviders[helpPId+'.secret']">
         </div>
     </div>
 </form>
 
-<p>Close the help panel and click <i>save changes</i>.</p>
\ No newline at end of file
+<p>Close the help panel and click <i>save changes</i>.</p>
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/provider/twitter-help.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/provider/twitter-help.html
old mode 100755
new mode 100644
index 4ce7621..27ea7ab
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/provider/twitter-help.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/provider/twitter-help.html
@@ -1,6 +1,5 @@
 <p>
-    Open <a href="https://dev.twitter.com/apps" target="_blank">https://dev.twitter.com/apps</a>. Click on <i>Create a
-    new
+    Open <a href="https://dev.twitter.com/apps" target="_blank">https://dev.twitter.com/apps</a>. Click on <i>Create a new
     application</i>.
 </p>
 
@@ -16,28 +15,23 @@
 
 <p>Insert <i>Consumer key</i> and <i>Consumer secret</i> in the form below.</p>
 
-<form class="form-horizontal" name="googleHelpForm">
+<form class="form-horizontal" name="twitterHelpForm">
     <div class="control-group">
         <label class="control-label" for="providerHelp.key">Consumer key </label>
-
         <div class="controls">
-            <input type="text" class="input-xlarge" id="providerHelp.key"
-                   data-ng-model="application.providers[providerHelp.index].key">
+            <input type="text" class="input-xlarge" id="providerHelp.key" ng-model="realm.socialProviders[helpPId+'.key']">
         </div>
     </div>
     <div class="control-group">
         <label class="control-label" for="providerHelp.secret">Consumer secret </label>
-
         <div class="controls">
-            <input type="text" class="input-xlarge" id="providerHelp.secret"
-                   data-ng-model="application.providers[providerHelp.index].secret">
+            <input type="text" class="input-xlarge" id="providerHelp.secret" ng-model="realm.socialProviders[helpPId+'.secret']">
         </div>
     </div>
 </form>
 
 <p>
-    Now click on <i>Settings</i> and tick the box <i>Allow this application to be used to Sign in with Twitter</i>, and
-    click on <i>Update
+    Now click on <i>Settings</i> and tick the box <i>Allow this application to be used to Sign in with Twitter</i>, and click on <i>Update
     this Twitter application's settings</i>.
 </p>
 
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-social.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-social.html
index d68727b..a102740 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-social.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-social.html
@@ -1,4 +1,4 @@
-<div id="wrapper" class="container">
+<div id="wrapper" class="container social-provider">
     <div class="row">
         <div class="bs-sidebar col-md-3 clearfix" data-ng-include data-src="'partials/realm-menu.html'"></div>
         <div id="content-area" class="col-md-9" role="main">
@@ -12,11 +12,61 @@
                 </ul>
             </div>
             <div id="content">
-                <h2 class="pull-left"><span>{{realm.realm}}</span> Social Providers</h2>
-                <p class="subtitle"></p>
+                <ol class="breadcrumb">
+                    <li><a href="#/realms/{{realm.id}}">{{realm.realm}}</a></li>
+                    <li><a href="#/realms/{{realm.id}}">Settings</a></li>
+                    <li class="active">Social</li>
+                </ol>
+                <h2><span>{{realm.realm}}</span> Social Providers Settings</h2>
                 <form name="realmForm" novalidate>
                     <fieldset>
-                        <legend uncollapsed><span class="text">Social Settings</span></legend>
+                        <div>
+                            <table>
+                                <caption class="hidden">Table of social providers</caption>
+                                <thead>
+                                <tr>
+                                    <th colspan="5" class="rcue-table-actions">
+                                        <div class="actions">
+                                            <div class="select-rcue">
+                                                <select ng-model="newProviderId"
+                                                        ng-options="p for p in unsetProviders"></select>
+                                            </div>
+                                            <div>
+                                                <button ng-click="addProvider()" ng-disabled="">Add Provider</button>
+                                            </div>
+                                        </div>
+                                    </th>
+                                </tr>
+                                <tr ng-show="configuredProviders.length > 0">
+                                    <th>Provider</th>
+                                    <th>Key <span class="required">*</span></th>
+                                    <th>Secret <span class="required">*</span></th>
+                                    <th colspan="1">Actions</th>
+                                </tr>
+                                </thead>
+                                <tbody ng-show="configuredProviders.length > 0">
+                                <tr ng-repeat="pId in configuredProviders">
+                                    <td>
+                                        <div class="clearfix">
+                                            <input class="input-small disabled" type="text" placeholder="Key" value="{{pId}}" readonly>
+                                        </div>
+                                    </td>
+                                    <td>
+                                        <input class="input-small" type="text" placeholder="Key" ng-model="realm.socialProviders[pId+'.key']"
+                                               ng-class="{'dirty': saveClicked}" required>
+                                    </td>
+                                    <td>
+                                        <input class="input-small" type="text" placeholder="Secret" ng-model="realm.socialProviders[pId+'.secret']"
+                                               ng-class="{'dirty': saveClicked}" required>
+                                    </td>
+                                    <td>
+                                        <div class="action-div"><i class="icon-question" ng-click="openHelp(pId)"></i></div>
+                                        <div class="action-div"><i class="icon-remove" ng-click="removeProvider(pId)"></i></div>
+                                    </td>
+                                </tr>
+                                </tbody>
+                            </table>
+                        </div>
                     </fieldset>
                     <div class="form-actions">
                         <button type="submit" data-ng-click="save()" class="primary" data-ng-show="changed">Save
@@ -25,9 +75,47 @@
                         <button type="submit" data-ng-click="reset()" data-ng-show="changed">Clear changes
                         </button>
                     </div>
-               </form>
+                </form>
             </div>
         </div>
         <div id="container-right-bg"></div>
     </div>
-</div>
\ No newline at end of file
+</div>
+
+<div modal="providerHelpModal" close="closeHelp()" options="opts">
+    <div class="modal-dialog">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h3>Configure {{helpPId}}</h3>
+            </div>
+            <div class="modal-body">
+                <div ng-include src="'partials/provider/'+ helpPId +'-help.html'"></div>
+            </div>
+            <div class="modal-footer">
+                <button class="btn" ng-click="closeHelp()">Close</button>
+            </div>
+        </div>
+    </div>
+</div>
+
+<!-- TODO remove once this page is properly styled -->
+<style type="text/css">
+    .social-provider input.ng-invalid.dirty,
+    .social-provider input.ng-invalid.ng-dirty {
+        background-color: #FFEEEE;
+    }
+
+    .social-provider .actions > div {
+        display: inline-block;
+        overflow: hidden;
+    }
+
+    .social-provider td {
+        font-size: 10px;
+    }
+
+    .social-provider .action-div {
+        display: inline-block;
+        margin: 5px;
+    }
+</style>
\ No newline at end of file
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/role-detail.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/role-detail.html
index fc33fc5..78eeda7 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/role-detail.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/role-detail.html
@@ -5,7 +5,7 @@
             <div class="top-nav">
                 <ul class="rcue-tabs">
                     <li><a href="#/realms/{{realm.id}}">General</a></li>
-                    <li data-ng-show="realm.social"><a href="#">Social</a></li>
+                    <li data-ng-show="realm.social"><a href="#/realms/{{realm.id}}/social-settings">Social</a></li>
                     <li class="active"><a href="#/realms/{{realm.id}}/roles">Roles</a></li>
                     <li><a href="#/realms/{{realm.id}}/required-credentials">Credentials</a></li>
                     <li><a href="#/realms/{{realm.id}}/token-settings">Token</a></li>
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/role-list.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/role-list.html
index bc006d1..69fbdcd 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/role-list.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/role-list.html
@@ -5,7 +5,7 @@
             <div class="top-nav">
                 <ul class="rcue-tabs">
                     <li><a href="#/realms/{{realm.id}}">General</a></li>
-                    <li data-ng-show="realm.social"><a href="#">Social</a></li>
+                    <li data-ng-show="realm.social"><a href="#/realms/{{realm.id}}/social-settings">Social</a></li>
                     <li class="active"><a href="#/realms/{{realm.id}}/roles">Roles</a></li>
                     <li><a href="#/realms/{{realm.id}}/required-credentials">Credentials</a></li>
                     <li><a href="#/realms/{{realm.id}}/token-settings">Token</a></li>
diff --git a/services/src/main/java/org/keycloak/services/managers/RealmManager.java b/services/src/main/java/org/keycloak/services/managers/RealmManager.java
index 1387f12..d0f3e95 100755
--- a/services/src/main/java/org/keycloak/services/managers/RealmManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/RealmManager.java
@@ -253,7 +253,7 @@ public class RealmManager {
             }
         }
 
-        if (rep.getAccountManagement() != null && rep.getAccountManagement()) {
+        if (rep.isAccountManagement() != null && rep.isAccountManagement()) {
             enableAccountManagement(newRealm);
         }