keycloak-aplcache

Details

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 fcd5d13..3371766 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
@@ -256,7 +256,7 @@ module.controller('RealmDetailCtrl', function($scope, Current, Realm, realm, $ht
     };
 });
 
-module.controller('RealmRequiredCredentialsCtrl', function($scope, Realm, realm, $http, $location, Dialog, Notifications) {
+module.controller('RealmRequiredCredentialsCtrl', function($scope, Realm, realm, $http, $location, Dialog, Notifications, PasswordPolicy) {
     console.log('RealmRequiredCredentialsCtrl');
 
     $scope.realm = {
@@ -264,128 +264,25 @@ module.controller('RealmRequiredCredentialsCtrl', function($scope, Realm, realm,
         requiredCredentials : realm.requiredCredentials,
         requiredApplicationCredentials : realm.requiredApplicationCredentials,
         requiredOAuthClientCredentials : realm.requiredOAuthClientCredentials,
-        registrationAllowed : realm.registrationAllowed
+        registrationAllowed : realm.registrationAllowed,
+        passwordPolicy: realm.passwordPolicy
     };
 
-    if (realm.hasOwnProperty('passwordPolicy')){
-        $scope.realm['passwordPolicy'] = realm.passwordPolicy;
-    } else {
-        $scope.realm['passwordPolicy'] = "";
-        realm['passwordPolicy'] = "";
-    }
-
     var oldCopy = angular.copy($scope.realm);
 
-    /* Map used in the table when hovering over (i) icon */
-    $scope.policyMessages = {
-        length:         "Minimal password length (integer type). Default value is 8.",
-        digits:         "Minimal number (integer type) of digits in password. Default value is 1.",
-        lowerCase:      "Minimal number (integer type) of lowercase characters in password. Default value is 1.",
-        upperCase:      "Minimal number (integer type) of uppercase characters in password. Default value is 1.",
-        specialChars:   "Minimal number (integer type) of special characters in password. Default value is 1."
-    }
+    $scope.allPolicies = PasswordPolicy.allPolicies;
+    $scope.policyMessages = PasswordPolicy.policyMessages;
 
-    // $scope.policy is an object representing passwordPolicy string
-    $scope.policy = {};
-    // All available policies
-    $scope.allPolicies = ['length', 'digits', 'lowerCase', 'upperCase', 'specialChars'];
-    // List of configured policies
-    $scope.configuredPolicies = [];
-    // List of not configured policies
-    $scope.availablePolicies = $scope.allPolicies.slice(0);
-
-    $scope.addPolicy = function(){
-        $scope.policy[$scope.newPolicyId] = "";
-        updateConfigured();
-    }
+    $scope.policy = PasswordPolicy.parse(realm.passwordPolicy);
 
-    $scope.removePolicy = function(pId){
-        delete $scope.policy[pId];
-        updateConfigured();
+    $scope.addPolicy = function(policy){
+        $scope.policy.push(policy);
     }
 
-    // Updating lists of configured and non-configured policies based on the $scope.policy object
-    var updateConfigured = function(){
-
-        for (var i = 0; i < $scope.allPolicies.length; i++){
-
-            var policy = $scope.allPolicies[i];
-
-            if($scope.policy.hasOwnProperty(policy)){
-
-                var ind = $scope.configuredPolicies.indexOf(policy);
-
-                if(ind < 0){
-                    $scope.configuredPolicies.push(policy);
-                }
-
-                ind = $scope.availablePolicies.indexOf(policy);
-                if(ind > -1){
-                    $scope.availablePolicies.splice(ind, 1);
-                }
-            } else {
-
-                var ind = $scope.configuredPolicies.indexOf(policy);
-
-                if(ind > -1){
-                    $scope.configuredPolicies.splice(ind, 1);
-                }
-
-                ind = $scope.availablePolicies.indexOf(policy);
-                if(ind < 0){
-                    $scope.availablePolicies.push(policy);
-                }
-            }
-        }
-
-        if ($scope.availablePolicies.length > 0){
-            $scope.newPolicyId = $scope.availablePolicies[0];
-        }
-    }
-
-    // Creating object from policy string
-    var evaluatePolicy = function(policyString){
-
-        var policyObject = {};
-
-        if (!policyString || policyString.length == 0){
-            return policyObject;
-        }
-
-        var policyArray = policyString.split(" and ");
-
-        for (var i = 0; i < policyArray.length; i ++){
-            var policyToken = policyArray[i];
-            var re = /(\w+)\(*(\d*)\)*/;
-
-            var policyEntry = re.exec(policyToken);
-            policyObject[policyEntry[1]] = policyEntry[2];
-        }
-
-        return policyObject;
-    }
-
-    // Creating policy string based on policy object
-    var generatePolicy = function(policyObject){
-        var policyString = "";
-
-        for (var key in policyObject){
-            policyString += key;
-            var value = policyObject[key];
-            if ( value != ""){
-                policyString += "("+value+")";
-            }
-            policyString += " and ";
-        }
-
-        policyString = policyString.substring(0, policyString.length - 5);
-
-        return policyString;
+    $scope.removePolicy = function(index){
+        $scope.policy.splice(index, 1);
     }
 
-    $scope.policy = evaluatePolicy(realm.passwordPolicy);
-    updateConfigured();
-
     $scope.userCredentialOptions = {
         'multiple' : true,
         'simple_tags' : true,
@@ -400,9 +297,9 @@ module.controller('RealmRequiredCredentialsCtrl', function($scope, Realm, realm,
         }
     }, true);
 
-    $scope.$watch('policy', function() {
-        $scope.realm.passwordPolicy = generatePolicy($scope.policy);
-        if ($scope.realm.passwordPolicy != realm.passwordPolicy){
+    $scope.$watch('policy', function(oldVal, newVal) {
+        if (oldVal != newVal) {
+            $scope.realm.passwordPolicy = PasswordPolicy.toString($scope.policy);
             $scope.changed = true;
         }
     }, true);
@@ -419,11 +316,8 @@ module.controller('RealmRequiredCredentialsCtrl', function($scope, Realm, realm,
 
     $scope.reset = function() {
         $scope.realm = angular.copy(oldCopy);
-
-        $scope.configuredPolicies = [];
-        $scope.availablePolicies = $scope.allPolicies.slice(0);
-        $scope.policy = evaluatePolicy(oldCopy.passwordPolicy);
-        updateConfigured();
+        $scope.policy = PasswordPolicy.parse(oldCopy.passwordPolicy);
+        console.debug(realm.passwordPolicy);
 
         $scope.changed = false;
     };
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/js/services.js b/admin-ui/src/main/resources/META-INF/resources/admin/js/services.js
index d1af959..193a8d3 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/js/services.js
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/js/services.js
@@ -386,3 +386,68 @@ module.factory('TimeUnit', function() {
 
     return t;
 });
+
+
+module.factory('PasswordPolicy', function() {
+    var p = {};
+
+    p.policyMessages = {
+        length:         "Minimal password length (integer type). Default value is 8.",
+        digits:         "Minimal number (integer type) of digits in password. Default value is 1.",
+        lowerCase:      "Minimal number (integer type) of lowercase characters in password. Default value is 1.",
+        upperCase:      "Minimal number (integer type) of uppercase characters in password. Default value is 1.",
+        specialChars:   "Minimal number (integer type) of special characters in password. Default value is 1."
+    }
+
+    p.allPolicies = [
+        { name: 'length', value: 8 },
+        { name: 'digits', value: 1 },
+        { name: 'lowerCase', value: 1 },
+        { name: 'upperCase', value: 1 },
+        { name: 'specialChars', value: 1 }
+    ];
+
+    p.parse = function(policyString) {
+        var policies = [];
+
+        if (!policyString || policyString.length == 0){
+            return policies;
+        }
+
+        var policyArray = policyString.split(" and ");
+
+        for (var i = 0; i < policyArray.length; i ++){
+            var policyToken = policyArray[i];
+            var re = /(\w+)\(*(\d*)\)*/;
+
+            var policyEntry = re.exec(policyToken);
+
+            policies.push({ name: policyEntry[1], value: parseInt(policyEntry[2]) });
+
+        }
+
+        return policies;
+    };
+
+    p.toString = function(policies) {
+        if (!policies || policies.length == 0) {
+            return null;
+        }
+
+        var policyString = "";
+
+        for (var i in policies){
+            policyString += policies[i].name;
+            if ( policies[i].value ){
+                policyString += '(' + policies[i].value + ')';
+            }
+            policyString += " and ";
+        }
+
+        policyString = policyString.substring(0, policyString.length - 5);
+
+        return policyString;
+    };
+
+    return p;
+});
\ No newline at end of file
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-credentials.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-credentials.html
index 0d81e01..d9e505c 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-credentials.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-credentials.html
@@ -52,18 +52,16 @@
                         <table>
                             <caption class="hidden">Table of Password Policies</caption>
                             <thead>
-                            <tr ng-show="availablePolicies.length > 0">
+                            <tr ng-show="(allPolicies|remove:policy:'name').length > 0">
                                 <th colspan="5" class="rcue-table-actions">
                                     <div class="actions">
                                         <div class="select-rcue">
-                                            <select ng-model="newPolicyId"
-                                                    ng-options="name as name for name in availablePolicies"
-                                                    placeholder="Please select">
+                                            <select ng-model="selectedPolicy"
+                                                    ng-options="p.name for p in (allPolicies|remove:policy:'name')"
+                                                    data-ng-change="addPolicy(selectedPolicy); selectedAllPolicies = null">
+                                                <option value="" disabled selected>Add policy...</option>
                                             </select>
                                         </div>
-                                        <div>
-                                            <button ng-click="addPolicy()" ng-disabled="">Add Policy</button>
-                                        </div>
                                     </div>
                                 </th>
                             </tr>
@@ -74,19 +72,19 @@
                             </tr>
                             </thead>
                             <tbody>
-                            <tr ng-repeat="name in configuredPolicies">
+                            <tr ng-repeat="p in policy">
                                 <td>
                                     <div class="clearfix">
-                                        <input class="input-small disabled" type="text" value="{{name}}" readonly>
+                                        <input class="input-small disabled" type="text" value="{{p.name}}" readonly>
                                     </div>
                                 </td>
                                 <td>
-                                    <input ng-model="policy[name]" type="number" placeholder="No value assigned" class="input-small">
+                                    <input ng-model="p.value" type="number" placeholder="No value assigned" class="input-small" min="1" max="50">
                                 </td>
                                 <td>
                                     <div class="action-div"><i class="icon-question" popover="{{policyMessages[name]}}"
                                                                popover-placement="left" popover-trigger="mouseenter"></i></div>
-                                    <div class="action-div"><i class="icon-remove" ng-click="removePolicy(name)"></i></div>
+                                    <div class="action-div"><i class="icon-remove" ng-click="removePolicy($index)"></i></div>
                                 </td>
                             </tr>
                             </tbody>