keycloak-memoizeit

Changes

Details

diff --git a/server-spi-private/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java b/server-spi-private/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java
index 43e8ef8..6637bd8 100755
--- a/server-spi-private/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java
+++ b/server-spi-private/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java
@@ -872,8 +872,6 @@ public class ModelToRepresentation {
                 return scope;
             }).collect(Collectors.toSet()));
 
-            resource.setTypedScopes(new ArrayList<>());
-
             if (resource.getType() != null) {
                 ResourceStore resourceStore = authorization.getStoreFactory().getResourceStore();
                 for (Resource typed : resourceStore.findByType(resource.getType(), resourceServer.getId())) {
diff --git a/services/src/main/java/org/keycloak/exportimport/util/ExportUtils.java b/services/src/main/java/org/keycloak/exportimport/util/ExportUtils.java
index 51ed405..25b309d 100755
--- a/services/src/main/java/org/keycloak/exportimport/util/ExportUtils.java
+++ b/services/src/main/java/org/keycloak/exportimport/util/ExportUtils.java
@@ -335,13 +335,15 @@ public class ExportUtils {
     private static PolicyRepresentation createPolicyRepresentation(AuthorizationProvider authorizationProvider, Policy policy) {
         KeycloakSession session = authorizationProvider.getKeycloakSession();
         RealmModel realm = authorizationProvider.getRealm();
-        StoreFactory storeFactory = authorizationProvider.getStoreFactory();
+
         try {
             PolicyRepresentation rep = toRepresentation(policy, PolicyRepresentation.class, authorizationProvider);
 
             rep.setId(null);
 
-            Map<String, String> config = rep.getConfig();
+            Map<String, String> config = new HashMap<>(rep.getConfig());
+
+            rep.setConfig(config);
 
             String roles = config.get("roles");
 
diff --git a/themes/src/main/resources/theme/base/admin/resources/js/authz/authz-app.js b/themes/src/main/resources/theme/base/admin/resources/js/authz/authz-app.js
index ecb008d..7c5e7fa 100644
--- a/themes/src/main/resources/theme/base/admin/resources/js/authz/authz-app.js
+++ b/themes/src/main/resources/theme/base/admin/resources/js/authz/authz-app.js
@@ -59,6 +59,23 @@ module.config(['$routeProvider', function ($routeProvider) {
             }
         },
         controller: 'ResourceServerDetailCtrl'
+    }).when('/realms/:realm/clients/:client/authz/resource-server/export-settings', {
+              templateUrl: resourceUrl + '/partials/authz/resource-server-export-settings.html',
+              resolve: {
+                  realm: function (RealmLoader) {
+                      return RealmLoader();
+                  },
+                  client : function(ClientLoader) {
+                      return ClientLoader();
+                  },
+                  clients: function (ClientListLoader) {
+                      return ClientListLoader();
+                  },
+                  serverInfo: function (ServerInfoLoader) {
+                      return ServerInfoLoader();
+                  }
+              },
+              controller: 'ResourceServerDetailCtrl'
     }).when('/realms/:realm/clients/:client/authz/resource-server/evaluate', {
         templateUrl: resourceUrl + '/partials/authz/policy/resource-server-policy-evaluate.html',
         resolve: {
diff --git a/themes/src/main/resources/theme/base/admin/resources/js/authz/authz-controller.js b/themes/src/main/resources/theme/base/admin/resources/js/authz/authz-controller.js
index 5d8d462..700d7f7 100644
--- a/themes/src/main/resources/theme/base/admin/resources/js/authz/authz-controller.js
+++ b/themes/src/main/resources/theme/base/admin/resources/js/authz/authz-controller.js
@@ -79,7 +79,72 @@ module.controller('ResourceServerDetailCtrl', function($scope, $http, $route, $l
     });
 });
 
-module.controller('ResourceServerResourceCtrl', function($scope, $http, $route, $location, realm, ResourceServer, ResourceServerResource, client) {
+var Resources = {
+    delete: function(ResourceServerResource, realm, client, $scope, AuthzDialog, $location, Notifications, $route) {
+        ResourceServerResource.permissions({
+            realm : realm,
+            client : client.id,
+            rsrid : $scope.resource._id
+        }, function (permissions) {
+            var msg = "";
+
+            if (permissions.length > 0 && !$scope.deleteConsent) {
+                msg = "<p>This resource is referenced in some permissions:</p>";
+                msg += "<ul>";
+                for (i = 0; i < permissions.length; i++) {
+                    msg+= "<li><strong>" + permissions[i].name + "</strong></li>";
+                }
+                msg += "</ul>";
+                msg += "<p>If you remove this resource, the permissions above will be affected and will not be associated with this resource anymore.</p>";
+            }
+
+            AuthzDialog.confirmDeleteWithMsg($scope.resource.name, "Resource", msg, function() {
+                ResourceServerResource.delete({realm : realm, client : $scope.client.id, rsrid : $scope.resource._id}, null, function() {
+                    $location.url("/realms/" + realm + "/clients/" + $scope.client.id + "/authz/resource-server/resource");
+                    $route.reload();
+                    Notifications.success("The resource has been deleted.");
+                });
+            });
+        });
+    }
+}
+
+var Policies = {
+    delete: function(service, realm, client, $scope, AuthzDialog, $location, Notifications, $route, isPermission) {
+        var msg = "";
+
+        service.dependentPolicies({
+            realm : realm,
+            client : client.id,
+            id : $scope.policy.id
+        }, function (dependentPolicies) {
+            if (dependentPolicies.length > 0 && !$scope.deleteConsent) {
+                msg = "<p>This policy is being used by other policies:</p>";
+                msg += "<ul>";
+                for (i = 0; i < dependentPolicies.length; i++) {
+                    msg+= "<li><strong>" + dependentPolicies[i].name + "</strong></li>";
+                }
+                msg += "</ul>";
+                msg += "<p>If you remove this policy, the policies above will be affected and will not be associated with this policy anymore.</p>";
+            }
+
+            AuthzDialog.confirmDeleteWithMsg($scope.policy.name, isPermission ? "Permission" : "Policy", msg, function() {
+                service.delete({realm : realm, client : $scope.client.id, id : $scope.policy.id}, null, function() {
+                    if (isPermission) {
+                        $location.url("/realms/" + realm + "/clients/" + $scope.client.id + "/authz/resource-server/permission");
+                        Notifications.success("The permission has been deleted.");
+                    } else {
+                        $location.url("/realms/" + realm + "/clients/" + $scope.client.id + "/authz/resource-server/policy");
+                        Notifications.success("The policy has been deleted.");
+                    }
+                    $route.reload();
+                });
+            });
+        });
+    }
+}
+
+module.controller('ResourceServerResourceCtrl', function($scope, $http, $route, $location, realm, ResourceServer, ResourceServerResource, client, AuthzDialog, Notifications) {
     $scope.realm = realm;
     $scope.client = client;
 
@@ -171,6 +236,11 @@ module.controller('ResourceServerResourceCtrl', function($scope, $http, $route, 
             }
         }
     };
+
+    $scope.delete = function(resource) {
+        $scope.resource = resource;
+        Resources.delete(ResourceServerResource, $route.current.params.realm, client, $scope, AuthzDialog, $location, Notifications, $route);
+    };
 });
 
 module.controller('ResourceServerResourceDetailCtrl', function($scope, $http, $route, $location, realm, ResourceServer, client, ResourceServerResource, ResourceServerScope, AuthzDialog, Notifications) {
@@ -282,30 +352,7 @@ module.controller('ResourceServerResourceDetailCtrl', function($scope, $http, $r
                 }
 
                 $scope.remove = function() {
-                    ResourceServerResource.permissions({
-                        realm : $route.current.params.realm,
-                        client : client.id,
-                        rsrid : $scope.resource._id
-                    }, function (permissions) {
-                        var msg = "";
-
-                        if (permissions.length > 0 && !$scope.deleteConsent) {
-                            msg = "<p>This resource is referenced in some policies:</p>";
-                            msg += "<ul>";
-                            for (i = 0; i < permissions.length; i++) {
-                                msg+= "<li><strong>" + permissions[i].name + "</strong></li>";
-                            }
-                            msg += "</ul>";
-                            msg += "<p>If you remove this resource, the policies above will be affected and will not be associated with this resource anymore.</p>";
-                        }
-
-                        AuthzDialog.confirmDeleteWithMsg($scope.resource.name, "Resource", msg, function() {
-                            ResourceServerResource.delete({realm : realm.realm, client : $scope.client.id, rsrid : $scope.resource._id}, null, function() {
-                                $location.url("/realms/" + realm.realm + "/clients/" + $scope.client.id + "/authz/resource-server/resource");
-                                Notifications.success("The resource has been deleted.");
-                            });
-                        });
-                    });
+                    Resources.delete(ResourceServerResource, $route.current.params.realm, client, $scope, AuthzDialog, $location, Notifications, $route);
                 }
 
                 $scope.reset = function() {
@@ -335,7 +382,37 @@ module.controller('ResourceServerResourceDetailCtrl', function($scope, $http, $r
     }
 });
 
-module.controller('ResourceServerScopeCtrl', function($scope, $http, $route, $location, realm, ResourceServer, ResourceServerScope, client) {
+var Scopes = {
+    delete: function(ResourceServerScope, realm, client, $scope, AuthzDialog, $location, Notifications, $route) {
+        ResourceServerScope.permissions({
+            realm : realm,
+            client : client.id,
+            id : $scope.scope.id
+        }, function (permissions) {
+            var msg = "";
+
+            if (permissions.length > 0 && !$scope.deleteConsent) {
+                msg = "<p>This scope is referenced in some permissions:</p>";
+                msg += "<ul>";
+                for (i = 0; i < permissions.length; i++) {
+                    msg+= "<li><strong>" + permissions[i].name + "</strong></li>";
+                }
+                msg += "</ul>";
+                msg += "<p>If you remove this scope, the permissions above will be affected and will not be associated with this scope anymore.</p>";
+            }
+
+            AuthzDialog.confirmDeleteWithMsg($scope.scope.name, "Scope", msg, function() {
+                ResourceServerScope.delete({realm : realm, client : $scope.client.id, id : $scope.scope.id}, null, function() {
+                    $location.url("/realms/" + realm + "/clients/" + $scope.client.id + "/authz/resource-server/scope");
+                    $route.reload();
+                    Notifications.success("The scope has been deleted.");
+                });
+            });
+        });
+    }
+}
+
+module.controller('ResourceServerScopeCtrl', function($scope, $http, $route, $location, realm, ResourceServer, ResourceServerScope,client, AuthzDialog, Notifications) {
     $scope.realm = realm;
     $scope.client = client;
 
@@ -427,6 +504,11 @@ module.controller('ResourceServerScopeCtrl', function($scope, $http, $route, $lo
             }
         }
     };
+
+    $scope.delete = function(scope) {
+        $scope.scope = scope;
+        Scopes.delete(ResourceServerScope, $route.current.params.realm, client, $scope, AuthzDialog, $location, Notifications, $route);
+    };
 });
 
 module.controller('ResourceServerScopeDetailCtrl', function($scope, $http, $route, $location, realm, ResourceServer, client, ResourceServerScope, AuthzDialog, Notifications) {
@@ -496,30 +578,7 @@ module.controller('ResourceServerScopeDetailCtrl', function($scope, $http, $rout
                 }
 
                 $scope.remove = function() {
-                    ResourceServerScope.permissions({
-                        realm : $route.current.params.realm,
-                        client : client.id,
-                        id : $scope.scope.id
-                    }, function (permissions) {
-                        var msg = "";
-
-                        if (permissions.length > 0 && !$scope.deleteConsent) {
-                            msg = "<p>This scope is referenced in some policies:</p>";
-                            msg += "<ul>";
-                            for (i = 0; i < permissions.length; i++) {
-                                msg+= "<li><strong>" + permissions[i].name + "</strong></li>";
-                            }
-                            msg += "</ul>";
-                            msg += "<p>If you remove this scope, the policies above will be affected and will not be associated with this scope anymore.</p>";
-                        }
-
-                        AuthzDialog.confirmDeleteWithMsg($scope.scope.name, "Scope", msg, function() {
-                            ResourceServerScope.delete({realm : realm.realm, client : $scope.client.id, id : $scope.scope.id}, null, function() {
-                                $location.url("/realms/" + realm.realm + "/clients/" + client.id + "/authz/resource-server/scope");
-                                Notifications.success("The scope has been deleted.");
-                            });
-                        });
-                    });
+                    Scopes.delete(ResourceServerScope, $route.current.params.realm, client, $scope, AuthzDialog, $location, Notifications, $route);
                 }
 
                 $scope.reset = function() {
@@ -548,7 +607,7 @@ module.controller('ResourceServerScopeDetailCtrl', function($scope, $http, $rout
     }
 });
 
-module.controller('ResourceServerPolicyCtrl', function($scope, $http, $route, $location, realm, ResourceServer, ResourceServerPolicy, PolicyProvider, client) {
+module.controller('ResourceServerPolicyCtrl', function($scope, $http, $route, $location, realm, ResourceServer, ResourceServerPolicy, PolicyProvider, client, AuthzDialog, Notifications) {
     $scope.realm = realm;
     $scope.client = client;
     $scope.policyProviders = [];
@@ -644,9 +703,14 @@ module.controller('ResourceServerPolicyCtrl', function($scope, $http, $route, $l
             }
         }
     };
+
+    $scope.delete = function(policy) {
+        $scope.policy = policy;
+        Policies.delete(ResourceServerPolicy, $route.current.params.realm, client, $scope, AuthzDialog, $location, Notifications, $route, false);
+    };
 });
 
-module.controller('ResourceServerPermissionCtrl', function($scope, $http, $route, $location, realm, ResourceServer, ResourceServerPermission, PolicyProvider, client) {
+module.controller('ResourceServerPermissionCtrl', function($scope, $http, $route, $location, realm, ResourceServer, ResourceServerPermission, PolicyProvider, client, AuthzDialog, Notifications) {
     $scope.realm = realm;
     $scope.client = client;
     $scope.policyProviders = [];
@@ -741,6 +805,11 @@ module.controller('ResourceServerPermissionCtrl', function($scope, $http, $route
             }
         }
     };
+
+    $scope.delete = function(policy) {
+        $scope.policy = policy;
+        Policies.delete(ResourceServerPermission, $route.current.params.realm, client, $scope, AuthzDialog, $location, Notifications, $route, true);
+    };
 });
 
 module.controller('ResourceServerPolicyDroolsDetailCtrl', function($scope, $http, $route, realm, client, PolicyController) {
@@ -1185,17 +1254,19 @@ module.controller('ResourceServerPolicyScopeDetailCtrl', function($scope, $route
                 client : client.id,
                 id : policy.id
             }, function(policies) {
-                $scope.selectedPolicies = [];
-                for (i = 0; i < policies.length; i++) {
-                    policies[i].text = policies[i].name;
-                    $scope.selectedPolicies.push(policies[i]);
-                }
-                var copy = angular.copy($scope.selectedPolicies);
-                $scope.$watch('selectedPolicies', function() {
-                    if (!angular.equals($scope.selectedPolicies, copy)) {
-                        $scope.changed = true;
+                if (policies.length > 0) {
+                    $scope.selectedPolicies = [];
+                    for (i = 0; i < policies.length; i++) {
+                        policies[i].text = policies[i].name;
+                        $scope.selectedPolicies.push(policies[i]);
                     }
-                }, true);
+                    var copy = angular.copy($scope.selectedPolicies);
+                    $scope.$watch('selectedPolicies', function() {
+                        if (!angular.equals($scope.selectedPolicies, copy)) {
+                            $scope.changed = true;
+                        }
+                    }, true);
+                }
             });
         },
 
@@ -1979,35 +2050,7 @@ module.service("PolicyController", function($http, $route, $location, ResourceSe
                 });
 
                 $scope.remove = function() {
-                    var msg = "";
-
-                    service.dependentPolicies({
-                        realm : $route.current.params.realm,
-                        client : client.id,
-                        id : $scope.policy.id
-                    }, function (dependentPolicies) {
-                        if (dependentPolicies.length > 0 && !$scope.deleteConsent) {
-                            msg = "<p>This policy is being used by other policies:</p>";
-                            msg += "<ul>";
-                            for (i = 0; i < dependentPolicies.length; i++) {
-                                msg+= "<li><strong>" + dependentPolicies[i].name + "</strong></li>";
-                            }
-                            msg += "</ul>";
-                            msg += "<p>If you remove this policy, the policies above will be affected and will not be associated with this policy anymore.</p>";
-                        }
-
-                        AuthzDialog.confirmDeleteWithMsg($scope.policy.name, "Policy", msg, function() {
-                            service.delete({realm : $scope.realm.realm, client : $scope.client.id, id : $scope.policy.id}, null, function() {
-                                if (delegate.isPermission()) {
-                                    $location.url("/realms/" + realm.realm + "/clients/" + client.id + "/authz/resource-server/permission");
-                                    Notifications.success("The permission has been deleted.");
-                                } else {
-                                    $location.url("/realms/" + realm.realm + "/clients/" + client.id + "/authz/resource-server/policy");
-                                    Notifications.success("The policy has been deleted.");
-                                }
-                            });
-                        });
-                    });
+                    Policies.delete(ResourceServerPolicy, $route.current.params.realm, client, $scope, AuthzDialog, $location, Notifications, $route, delegate.isPermission());
                 }
             }
         });
diff --git a/themes/src/main/resources/theme/base/admin/resources/partials/authz/permission/provider/resource-server-policy-resource-detail.html b/themes/src/main/resources/theme/base/admin/resources/partials/authz/permission/provider/resource-server-policy-resource-detail.html
index 221a902..6a02a0a 100644
--- a/themes/src/main/resources/theme/base/admin/resources/partials/authz/permission/provider/resource-server-policy-resource-detail.html
+++ b/themes/src/main/resources/theme/base/admin/resources/partials/authz/permission/provider/resource-server-policy-resource-detail.html
@@ -81,7 +81,7 @@
 
         <div class="form-group" data-ng-show="access.manageAuthorization">
             <div class="col-md-10 col-md-offset-2">
-                <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button>
+                <button kc-save data-ng-disabled="!changed || (selectedPolicies == null || selectedPolicies.length == 0)">{{:: 'save' | translate}}</button>
                 <button kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button>
             </div>
         </div>
diff --git a/themes/src/main/resources/theme/base/admin/resources/partials/authz/permission/provider/resource-server-policy-scope-detail.html b/themes/src/main/resources/theme/base/admin/resources/partials/authz/permission/provider/resource-server-policy-scope-detail.html
index cce7e24..79cec9a 100644
--- a/themes/src/main/resources/theme/base/admin/resources/partials/authz/permission/provider/resource-server-policy-scope-detail.html
+++ b/themes/src/main/resources/theme/base/admin/resources/partials/authz/permission/provider/resource-server-policy-scope-detail.html
@@ -85,7 +85,7 @@
         </fieldset>
         <div class="form-group" data-ng-show="access.manageAuthorization">
             <div class="col-md-10 col-md-offset-2">
-                <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button>
+                <button kc-save data-ng-disabled="!changed || ((selectedPolicies == null || selectedPolicies.length == 0) || (selectedScopes == null || selectedScopes.length == 0))">{{:: 'save' | translate}}</button>
                 <button kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button>
             </div>
         </div>
diff --git a/themes/src/main/resources/theme/base/admin/resources/partials/authz/permission/resource-server-permission-list.html b/themes/src/main/resources/theme/base/admin/resources/partials/authz/permission/resource-server-permission-list.html
index 2101643..2ee735b 100644
--- a/themes/src/main/resources/theme/base/admin/resources/partials/authz/permission/resource-server-permission-list.html
+++ b/themes/src/main/resources/theme/base/admin/resources/partials/authz/permission/resource-server-permission-list.html
@@ -62,12 +62,12 @@
                 <th>{{:: 'name' | translate}}</th>
                 <th>{{:: 'description' | translate}}</th>
                 <th>{{:: 'type' | translate}}</th>
-                <th>{{:: 'actions' | translate}}</th>
+                <th colspan="3">{{:: 'actions' | translate}}</th>
             </tr>
         </thead>
         <tfoot data-ng-show="policies && (policies.length >= query.max || query.first > 0)">
         <tr>
-            <td colspan="7">
+            <td colspan="8">
                 <div class="table-nav">
                     <button data-ng-click="firstPage()" class="first" ng-disabled="query.first == 0">{{:: 'first-page' | translate}}</button>
                     <button data-ng-click="previousPage()" class="prev" ng-disabled="query.first == 0">{{:: 'previous-page' | translate}}</button>
@@ -87,9 +87,12 @@
                 <td ng-if="policy.details.loaded" class="kc-action-cell" data-ng-click="showDetails(policy);">
                     {{:: 'authz-hide-details' | translate}}
                 </td>
+                <td class="kc-action-cell" ng-click="delete(policy);">
+                    {{:: 'delete' | translate}}
+                </td>
             </tr>
             <tr ng-if="policy.details && policy.details.loaded" ng-repeat-end="">
-                <td colspan="4">
+                <td colspan="5">
                     <div id="details">
                         <table class="table kc-authz-table-expanded table-striped">
                             <thead>
diff --git a/themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/provider/resource-server-policy-aggregate-detail.html b/themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/provider/resource-server-policy-aggregate-detail.html
index 4af440b..11d0827 100644
--- a/themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/provider/resource-server-policy-aggregate-detail.html
+++ b/themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/provider/resource-server-policy-aggregate-detail.html
@@ -71,7 +71,7 @@
 
         <div class="form-group" data-ng-show="access.manageAuthorization">
             <div class="col-md-10 col-md-offset-2">
-                <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button>
+                <button kc-save data-ng-disabled="!changed || (selectedPolicies == null || selectedPolicies.length == 0)">{{:: 'save' | translate}}</button>
                 <button kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button>
             </div>
         </div>
diff --git a/themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/resource-server-policy-list.html b/themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/resource-server-policy-list.html
index f4e0e89..8fe2117 100644
--- a/themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/resource-server-policy-list.html
+++ b/themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/resource-server-policy-list.html
@@ -63,12 +63,12 @@
                 <th>{{:: 'name' | translate}}</th>
                 <th>{{:: 'description' | translate}}</th>
                 <th>{{:: 'type' | translate}}</th>
-                <th>{{:: 'actions' | translate}}</th>
+                <th colspan="3">{{:: 'actions' | translate}}</th>
             </tr>
         </thead>
         <tfoot data-ng-show="policies && (policies.length >= query.max || query.first > 0)">
         <tr>
-            <td colspan="7">
+            <td colspan="8">
                 <div class="table-nav">
                     <button data-ng-click="firstPage()" class="first" ng-disabled="query.first == 0">{{:: 'first-page' | translate}}</button>
                     <button data-ng-click="previousPage()" class="prev" ng-disabled="query.first == 0">{{:: 'previous-page' | translate}}</button>
@@ -88,9 +88,12 @@
                 <td ng-if="policy.details.loaded" class="kc-action-cell" data-ng-click="showDetails(policy);">
                     {{:: 'authz-hide-details' | translate}}
                 </td>
+                <td class="kc-action-cell" ng-click="delete(policy);">
+                    {{:: 'delete' | translate}}
+                </td>
             </tr>
             <tr ng-if="policy.details && policy.details.loaded" ng-repeat-end="">
-                <td colspan="4">
+                <td colspan="5">
                     <div id="details">
                         <table class="table kc-authz-table-expanded table-striped">
                             <thead>
diff --git a/themes/src/main/resources/theme/base/admin/resources/partials/authz/resource-server-detail.html b/themes/src/main/resources/theme/base/admin/resources/partials/authz/resource-server-detail.html
index 3c28f6b..092280f 100644
--- a/themes/src/main/resources/theme/base/admin/resources/partials/authz/resource-server-detail.html
+++ b/themes/src/main/resources/theme/base/admin/resources/partials/authz/resource-server-detail.html
@@ -57,29 +57,6 @@
                 </div>
             </div>
         </fieldset>
-
-        <fieldset class="border-top" data-ng-show="server.id">
-            <legend><span class="text">{{:: 'authz-export-settings' | translate}}</span>
-                <kc-tooltip>{{:: 'authz-export-settings.tooltip' | translate}}</kc-tooltip>
-            </legend>
-            <div class="form-group">
-                <label class="col-md-2 control-label" for="server.allowRemoteResourceManagement">{{:: 'authz-export-settings' | translate}}</label>
-                <div class="col-md-6">
-                    <button data-ng-click="export()" class="btn btn-primary" data-ng-hide="settings">{{:: 'export' | translate}}</button>
-                    <button data-ng-click="downloadSettings()" class="btn btn-primary" data-ng-show="settings">{{:: 'download' | translate}}</button>
-                    <button data-ng-click="cancelExport()" class="btn btn-primary" data-ng-show="settings">{{:: 'cancel' | translate}}</button>
-                </div>
-                <kc-tooltip>{{:: 'authz-export-settings.tooltip' | translate}}</kc-tooltip>
-            </div>
-            <fieldset class="margin-top">
-                <div class="form-group" ng-show="settings">
-                    <div class="col-sm-12">
-                        <a class="btn btn-primary btn-lg" data-ng-click="download()" type="submit" ng-show="installation">{{:: 'download' | translate}}</a>
-                        <textarea class="form-control" rows="20" kc-select-action="click">{{settings}}</textarea>
-                    </div>
-                </div>
-            </fieldset>
-        </fieldset>
     </form>
 </div>
 
diff --git a/themes/src/main/resources/theme/base/admin/resources/partials/authz/resource-server-export-settings.html b/themes/src/main/resources/theme/base/admin/resources/partials/authz/resource-server-export-settings.html
new file mode 100644
index 0000000..86505db
--- /dev/null
+++ b/themes/src/main/resources/theme/base/admin/resources/partials/authz/resource-server-export-settings.html
@@ -0,0 +1,35 @@
+<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
+
+    <ol class="breadcrumb">
+        <li><a href="#/realms/{{realm.realm}}/clients">{{:: 'clients' | translate}}</a></li>
+        <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li>
+        <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server">{{:: 'authz-authorization' | translate}}</a></li>
+        <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server">{{:: 'export-settings' | translate}}</a></li>
+    </ol>
+
+    <kc-tabs-resource-server></kc-tabs-resource-server>
+
+    <form class="form-horizontal" name="exportForm" novalidate>
+        <fieldset>
+            <div class="form-group">
+                <label class="col-md-2 control-label">{{:: 'authz-export-settings' | translate}}</label>
+                <div class="col-md-6">
+                    <button data-ng-click="export()" class="btn btn-primary" data-ng-hide="settings">{{:: 'export' | translate}}</button>
+                    <button data-ng-click="downloadSettings()" class="btn btn-primary" data-ng-show="settings">{{:: 'download' | translate}}</button>
+                    <button data-ng-click="cancelExport()" class="btn btn-primary" data-ng-show="settings">{{:: 'cancel' | translate}}</button>
+                </div>
+                <kc-tooltip>{{:: 'authz-export-settings.tooltip' | translate}}</kc-tooltip>
+            </div>
+            <fieldset class="margin-top">
+                <div class="form-group" ng-show="settings">
+                    <div class="col-sm-12">
+                        <a class="btn btn-primary btn-lg" data-ng-click="download()" type="submit" ng-show="installation">{{:: 'download' | translate}}</a>
+                        <textarea class="form-control" rows="20" kc-select-action="click">{{settings}}</textarea>
+                    </div>
+                </div>
+            </fieldset>
+        </fieldset>
+    </form>
+</div>
+
+<kc-menu></kc-menu>
\ No newline at end of file
diff --git a/themes/src/main/resources/theme/base/admin/resources/partials/authz/resource-server-resource-list.html b/themes/src/main/resources/theme/base/admin/resources/partials/authz/resource-server-resource-list.html
index 3080ce1..924edbc 100644
--- a/themes/src/main/resources/theme/base/admin/resources/partials/authz/resource-server-resource-list.html
+++ b/themes/src/main/resources/theme/base/admin/resources/partials/authz/resource-server-resource-list.html
@@ -64,7 +64,7 @@
                 <th>{{:: 'type' | translate}}</th>
                 <th>{{:: 'authz-uri' | translate}}</th>
                 <th>{{:: 'authz-owner' | translate}}</th>
-                <th colspan="2">{{:: 'actions' | translate}}</th>
+                <th colspan="3">{{:: 'actions' | translate}}</th>
             </tr>
         </thead>
         <tfoot data-ng-show="resources && (resources.length >= query.max || query.first > 0)">
@@ -99,9 +99,12 @@
                 <td class="kc-action-cell" ng-click="createPolicy(resource);">
                     {{:: 'authz-create-permission' | translate}}
                 </td>
+                <td class="kc-action-cell" ng-click="delete(resource);">
+                    {{:: 'delete' | translate}}
+                </td>
             </tr>
             <tr ng-if="resource.details && resource.details.loaded" ng-repeat-end="">
-                <td colspan="6">
+                <td colspan="7">
                     <div id="details">
                         <table class="table kc-authz-table-expanded table-striped">
                             <thead>
diff --git a/themes/src/main/resources/theme/base/admin/resources/partials/authz/resource-server-scope-list.html b/themes/src/main/resources/theme/base/admin/resources/partials/authz/resource-server-scope-list.html
index 8153935..519c9f5 100644
--- a/themes/src/main/resources/theme/base/admin/resources/partials/authz/resource-server-scope-list.html
+++ b/themes/src/main/resources/theme/base/admin/resources/partials/authz/resource-server-scope-list.html
@@ -36,7 +36,7 @@
             </tr>
             <tr data-ng-hide="scopes.length == 0">
                 <th>{{:: 'name' | translate}}</th>
-                <th colspan="2">{{:: 'actions' | translate}}</th>
+                <th colspan="3">{{:: 'actions' | translate}}</th>
             </tr>
         </thead>
         <tfoot data-ng-show="scopes && (scopes.length >= query.max || query.first > 0)">
@@ -52,7 +52,7 @@
         </tfoot>
         <tbody>
             <tr ng-repeat-start="scope in scopes | filter:search | orderBy:'name'">
-                <td><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server/scope/{{scope.id}}">{{scope.name}}</a></td>
+                <td width="70%"><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server/scope/{{scope.id}}">{{scope.name}}</a></td>
                 <td ng-if="!scope.details.loaded" class="kc-action-cell" data-ng-click="showDetails(scope);">
                     {{:: 'authz-show-details' | translate}}
                 </td>
@@ -62,9 +62,12 @@
                 <td class="kc-action-cell" ng-click="createPolicy(scope);">
                     {{:: 'authz-create-permission' | translate}}
                 </td>
+                <td class="kc-action-cell" ng-click="delete(scope);">
+                    {{:: 'delete' | translate}}
+                </td>
             </tr>
             <tr ng-if="scope.details && scope.details.loaded" ng-repeat-end="">
-                <td colspan="3">
+                <td colspan="4">
                     <div id="details">
                         <table class="table kc-authz-table-expanded table-striped">
                             <thead>
diff --git a/themes/src/main/resources/theme/base/admin/resources/templates/authz/kc-tabs-resource-server.html b/themes/src/main/resources/theme/base/admin/resources/templates/authz/kc-tabs-resource-server.html
index 0491364..bd20270 100755
--- a/themes/src/main/resources/theme/base/admin/resources/templates/authz/kc-tabs-resource-server.html
+++ b/themes/src/main/resources/theme/base/admin/resources/templates/authz/kc-tabs-resource-server.html
@@ -9,5 +9,6 @@
         <li ng-class="{active: path[6] == 'policy'}" data-ng-hide="create"><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server/policy">{{:: 'authz-policies' | translate}}</a></li>
         <li ng-class="{active: path[6] == 'permission'}" data-ng-hide="create"><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server/permission">{{:: 'authz-permissions' | translate}}</a></li>
         <li ng-class="{active: path[6] == 'evaluate'}" data-ng-hide="create"><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server/evaluate">{{:: 'authz-evaluate' | translate}}</a></li>
+        <li ng-class="{active: path[6] == 'export-settings'}" data-ng-hide="create"><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server/export-settings">{{:: 'authz-export-settings' | translate}}</a></li>
     </ul>
 </div>
\ No newline at end of file