=== modified file 'src/maasserver/static/js/angular/controllers/node_details.js' --- src/maasserver/static/js/angular/controllers/node_details.js 2015-10-28 20:59:21 +0000 +++ src/maasserver/static/js/angular/controllers/node_details.js 2015-11-03 04:58:42 +0000 @@ -477,6 +477,15 @@ } } + // Return true if user is a super user/ + $scope.isSuperUser = function() { + var authUser = UsersManager.getAuthUser(); + if(!angular.isObject(authUser)) { + return false; + } + return authUser.is_superuser; + }; + // Called for autocomplete when the user is typing a tag name. $scope.tagsAutocomplete = function(query) { return TagsManager.autocomplete(query); === modified file 'src/maasserver/static/js/angular/controllers/node_details_networking.js' --- src/maasserver/static/js/angular/controllers/node_details_networking.js 2015-11-01 00:22:00 +0000 +++ src/maasserver/static/js/angular/controllers/node_details_networking.js 2015-11-03 04:58:42 +0000 @@ -462,14 +462,6 @@ updateLoaded(); }; - // Return true if user is a super user/ - $scope.isSuperUser = function() { - var authUser = UsersManager.getAuthUser(); - if(!angular.isObject(authUser)) { - return false; - } - return authUser.is_superuser; - }; // Return true if the networking information cannot be edited. // (it can't be changed when the node is in any state other === modified file 'src/maasserver/static/js/angular/controllers/node_details_storage.js' --- src/maasserver/static/js/angular/controllers/node_details_storage.js 2015-10-30 01:43:06 +0000 +++ src/maasserver/static/js/angular/controllers/node_details_storage.js 2015-11-03 04:58:42 +0000 @@ -43,8 +43,8 @@ }); angular.module('MAAS').controller('NodeStorageController', [ - '$scope', 'NodesManager', 'ConverterService', - function($scope, NodesManager, ConverterService) { + '$scope', 'NodesManager', 'ConverterService', 'UsersManager', + function($scope, NodesManager, ConverterService, UsersManager) { var PARTITION_TABLE_EXTRA_SPACE = 3 * 1024 * 1024; var MIN_PARTITION_SIZE = 2 * 1024 * 1024; var MIN_LOGICAL_VOLUME_SIZE = MIN_PARTITION_SIZE; @@ -595,10 +595,11 @@ // Return true if checkboxes in the filesystem section should be // disabled. $scope.isFilesystemsDisabled = function() { - return ( + return (( $scope.filesystemMode !== SELECTION_MODE.NONE && $scope.filesystemMode !== SELECTION_MODE.SINGLE && - $scope.filesystemMode !== SELECTION_MODE.MUTLI); + $scope.filesystemMode !== SELECTION_MODE.MUTLI) || + $scope.isAllStorageDisabled()); }; // Cancel the current filesystem operation. @@ -730,15 +731,17 @@ // Return true if checkboxes in the avaiable section should be // disabled. $scope.isAvailableDisabled = function() { - return ( + return (( $scope.availableMode !== SELECTION_MODE.NONE && $scope.availableMode !== SELECTION_MODE.SINGLE && - $scope.availableMode !== SELECTION_MODE.MUTLI); + $scope.availableMode !== SELECTION_MODE.MUTLI) || + $scope.isAllStorageDisabled()); }; // Return true if the disk can be formatted and mounted. $scope.canFormatAndMount = function(disk) { - if(disk.type === "lvm-vg" || disk.has_partitions) { + if($scope.isAllStorageDisabled() || + disk.type === "lvm-vg" || disk.has_partitions) { return false; } else { return true; @@ -765,7 +768,9 @@ // Return true if a partition can be added to disk. $scope.canAddPartition = function(disk) { - if(disk.type === "partition" || disk.type === "lvm-vg") { + if(!$scope.isSuperUser() || $scope.isAllStorageDisabled()) { + return false; + } else if(disk.type === "partition" || disk.type === "lvm-vg") { return false; } else if(disk.type === "virtual" && disk.parent_type === "lvm-vg") { @@ -935,7 +940,9 @@ // Return true if the disk can be deleted. $scope.canDelete = function(disk) { - if(disk.type === "lvm-vg") { + if(!$scope.isSuperUser() || $scope.isAllStorageDisabled()) { + return false; + } else if(disk.type === "lvm-vg") { return disk.original.used_size === 0; } else { if(!disk.has_partitions && ( @@ -1166,10 +1173,12 @@ // Return true if checkboxes in the cache sets section should be // disabled. $scope.isCacheSetsDisabled = function() { - return ( + return (( + $scope.isAllStorageDisabled() && + !$scope.isSuperUser()) || ( $scope.cachesetsMode !== SELECTION_MODE.NONE && $scope.cachesetsMode !== SELECTION_MODE.SINGLE && - $scope.cachesetsMode !== SELECTION_MODE.MUTLI); + $scope.cachesetsMode !== SELECTION_MODE.MUTLI)); }; // Cancel the current cache set operation. @@ -1179,7 +1188,9 @@ // Can delete the cache set. $scope.canDeleteCacheSet = function(cacheset) { - return cacheset.used_by === ""; + return (cacheset.used_by === "" && + !$scope.isAllStorageDisabled() && + $scope.isSuperUser()); }; // Enter delete mode. @@ -1207,7 +1218,7 @@ // Return true if a cache set can be created. $scope.canCreateCacheSet = function() { - if($scope.isAvailableDisabled()) { + if($scope.isAvailableDisabled() || !$scope.isSuperUser()) { return false; } @@ -1239,7 +1250,7 @@ // Return true if a bcache can be created. $scope.canCreateBcache = function() { - if($scope.isAvailableDisabled()) { + if($scope.isAvailableDisabled() || ! $scope.isSuperUser()) { return false; } @@ -1349,7 +1360,7 @@ // Return true if a RAID can be created. $scope.canCreateRAID = function() { - if($scope.isAvailableDisabled()) { + if($scope.isAvailableDisabled() || !$scope.isSuperUser()) { return false; } @@ -1555,7 +1566,7 @@ // Return true if a volume group can be created. $scope.canCreateVolumeGroup = function() { - if($scope.isAvailableDisabled()) { + if($scope.isAvailableDisabled() || !$scope.isSuperUser()) { return false; } @@ -1726,7 +1737,10 @@ // Return true when tags can be edited. $scope.canEditTags = function(disk) { - return disk.type !== "partition" && disk.type !== "lvm-vg"; + return (disk.type !== "partition" && + disk.type !== "lvm-vg" && + !$scope.isAllStorageDisabled() && + $scope.isSuperUser()); }; // Called to enter tag editing mode @@ -1753,4 +1767,24 @@ disk.tags = disk.$options.tags; disk.$options = {}; }; + + // Returns true if storage cannot be edited. + // (it can't be changed when the node is in any state other + // than Ready or Allocated) + $scope.isAllStorageDisabled = function() { + var authUser = UsersManager.getAuthUser(); + if(!angular.isObject(authUser) || !angular.isObject($scope.node) || + (!authUser.is_superuser && + authUser.username !== $scope.node.owner)) { + return true; + }else if (angular.isObject($scope.node) && + ["Ready", "Allocated"].indexOf( + $scope.node.status) === -1) { + // If the node is not ready or allocated, disable storage panel. + return true; + } else { + // The node must be either ready or broken. Enable it. + return false; + } + }; }]); === modified file 'src/maasserver/static/js/angular/controllers/tests/test_node_details.js' --- src/maasserver/static/js/angular/controllers/tests/test_node_details.js 2015-10-28 20:59:21 +0000 +++ src/maasserver/static/js/angular/controllers/tests/test_node_details.js 2015-11-03 04:58:42 +0000 @@ -679,6 +679,22 @@ }); }); + describe("isSuperUser", function() { + it("returns true if the user is a superuser", function() { + var controller = makeController(); + spyOn(UsersManager, "getAuthUser").and.returnValue( + { is_superuser: true }); + expect($scope.isSuperUser()).toBe(true); + }); + + it("returns false if the user is not a superuser", function() { + var controller = makeController(); + spyOn(UsersManager, "getAuthUser").and.returnValue( + { is_superuser: false }); + expect($scope.isSuperUser()).toBe(false); + }); + }); + describe("getPowerStateClass", function() { it("returns blank if no node", function() { === modified file 'src/maasserver/static/js/angular/controllers/tests/test_node_details_networking.js' --- src/maasserver/static/js/angular/controllers/tests/test_node_details_networking.js 2015-11-01 00:22:00 +0000 +++ src/maasserver/static/js/angular/controllers/tests/test_node_details_networking.js 2015-11-03 04:58:42 +0000 @@ -2784,37 +2784,18 @@ }); }); - describe("isSuperUser", function() { - it("returns true if the user is a superuser", function() { - var controller = makeController(); - spyOn(UsersManager, "getAuthUser").and.returnValue( - { is_superuser: true }); - expect($scope.isSuperUser()).toBe(true); - }); - - it("returns false if the user is not a superuser", function() { - var controller = makeController(); - spyOn(UsersManager, "getAuthUser").and.returnValue( - { is_superuser: false }); - expect($scope.isSuperUser()).toBe(false); - }); - }); - describe("isAllNetworkingDisabled", function() { it("returns true if the user is not a superuser and the node is ready", function() { var controller = makeController(); - spyOn(UsersManager, "getAuthUser").and.returnValue( - { is_superuser: false }); - expect($scope.isSuperUser()).toBe(false); + $scope.isSuperUser = function() { return false; }; expect($scope.isAllNetworkingDisabled()).toBe(true); }); it("return false if the node is Ready and we are a superuser", function() { var controller = makeController(); - spyOn(UsersManager, "getAuthUser").and.returnValue( - { is_superuser: true }); + $scope.isSuperUser = function() { return true; }; $scope.node.status = "Ready"; expect($scope.isAllNetworkingDisabled()).toBe(false); }); @@ -2822,8 +2803,7 @@ it("return false if the node is broken and we are a superuser", function() { var controller = makeController(); - spyOn(UsersManager, "getAuthUser").and.returnValue( - { is_superuser: true }); + $scope.isSuperUser = function() { return true; }; $scope.node.status = "Broken"; expect($scope.isAllNetworkingDisabled()).toBe(false); }); @@ -2831,8 +2811,7 @@ it("return true if the node is deploying and we are a superuser", function() { var controller = makeController(); - spyOn(UsersManager, "getAuthUser").and.returnValue( - { is_superuser: true }); + $scope.isSuperUser = function() { return true; }; $scope.node.status = "Deploying"; expect($scope.isAllNetworkingDisabled()).toBe(true); }); === modified file 'src/maasserver/static/js/angular/controllers/tests/test_node_details_storage.js' --- src/maasserver/static/js/angular/controllers/tests/test_node_details_storage.js 2015-10-30 01:43:06 +0000 +++ src/maasserver/static/js/angular/controllers/tests/test_node_details_storage.js 2015-11-03 04:58:42 +0000 @@ -669,6 +669,7 @@ it("returns false for NONE", function() { var controller = makeController(); $scope.filesystemMode = null; + spyOn($scope, "isAllStorageDisabled").and.returnValue(false); expect($scope.isFilesystemsDisabled()).toBe(false); }); @@ -676,6 +677,7 @@ it("returns false for SINGLE", function() { var controller = makeController(); $scope.filesystemMode = "single"; + spyOn($scope, "isAllStorageDisabled").and.returnValue(false); expect($scope.isFilesystemsDisabled()).toBe(false); }); @@ -683,6 +685,7 @@ it("returns false for MULTI", function() { var controller = makeController(); $scope.filesystemMode = "multi"; + spyOn($scope, "isAllStorageDisabled").and.returnValue(false); expect($scope.isFilesystemsDisabled()).toBe(false); }); @@ -690,6 +693,15 @@ it("returns true for UNMOUNT", function() { var controller = makeController(); $scope.filesystemMode = "unmount"; + spyOn($scope, "isAllStorageDisabled").and.returnValue(false); + + expect($scope.isFilesystemsDisabled()).toBe(true); + }); + + it("returns true when isAllStorageDisabled", function() { + var controller = makeController(); + $scope.filesystemMode = "multi"; + spyOn($scope, "isAllStorageDisabled").and.returnValue(true); expect($scope.isFilesystemsDisabled()).toBe(true); }); @@ -1100,6 +1112,7 @@ it("returns false for NONE", function() { var controller = makeController(); $scope.availableMode = null; + spyOn($scope, "isAllStorageDisabled").and.returnValue(false); expect($scope.isAvailableDisabled()).toBe(false); }); @@ -1107,6 +1120,7 @@ it("returns false for SINGLE", function() { var controller = makeController(); $scope.availableMode = "single"; + spyOn($scope, "isAllStorageDisabled").and.returnValue(false); expect($scope.isAvailableDisabled()).toBe(false); }); @@ -1114,6 +1128,7 @@ it("returns false for MULTI", function() { var controller = makeController(); $scope.availableMode = "multi"; + spyOn($scope, "isAllStorageDisabled").and.returnValue(false); expect($scope.isAvailableDisabled()).toBe(false); }); @@ -1121,6 +1136,7 @@ it("returns true for UNMOUNT", function() { var controller = makeController(); $scope.availableMode = "unmount"; + spyOn($scope, "isAllStorageDisabled").and.returnValue(false); expect($scope.isAvailableDisabled()).toBe(true); }); @@ -1131,18 +1147,21 @@ it("returns false if lvm-vg", function() { var controller = makeController(); var disk = { type: "lvm-vg" }; + spyOn($scope, "isAllStorageDisabled").and.returnValue(false); expect($scope.canFormatAndMount(disk)).toBe(false); }); it("returns false if has_partitions", function() { var controller = makeController(); var disk = { type: "physical", has_partitions: true }; + spyOn($scope, "isAllStorageDisabled").and.returnValue(false); expect($scope.canFormatAndMount(disk)).toBe(false); }); it("returns true otherwise", function() { var controller = makeController(); var disk = { type: "physical", has_partitions: false }; + spyOn($scope, "isAllStorageDisabled").and.returnValue(false); expect($scope.canFormatAndMount(disk)).toBe(true); }); }); @@ -1183,6 +1202,8 @@ it("returns false if partition", function() { var controller = makeController(); + spyOn($scope, "isAllStorageDisabled").and.returnValue(false); + $scope.isSuperUser = function() { return true; }; expect($scope.canAddPartition({ type: "partition" })).toBe(false); @@ -1190,6 +1211,8 @@ it("returns false if lvm-vg", function() { var controller = makeController(); + spyOn($scope, "isAllStorageDisabled").and.returnValue(false); + $scope.isSuperUser = function() { return true; }; expect($scope.canAddPartition({ type: "lvm-vg" })).toBe(false); @@ -1197,6 +1220,8 @@ it("returns false if logical volume", function() { var controller = makeController(); + spyOn($scope, "isAllStorageDisabled").and.returnValue(false); + $scope.isSuperUser = function() { return true; }; expect($scope.canAddPartition({ type: "virtual", parent_type: "lvm-vg" @@ -1205,6 +1230,8 @@ it("returns false if formatted", function() { var controller = makeController(); + spyOn($scope, "isAllStorageDisabled").and.returnValue(false); + $scope.isSuperUser = function() { return true; }; expect($scope.canAddPartition({ type: "physical", fstype: "ext4" @@ -1223,6 +1250,8 @@ block_size: 1024 } }; + spyOn($scope, "isAllStorageDisabled").and.returnValue(false); + $scope.isSuperUser = function() { return true; }; expect($scope.canAddPartition(disk)).toBe(false); }); @@ -1238,9 +1267,43 @@ block_size: 1024 } }; + spyOn($scope, "isAllStorageDisabled").and.returnValue(false); + $scope.isSuperUser = function() { return true; }; expect($scope.canAddPartition(disk)).toBe(false); }); + it("returns false if not super user", function() { + var controller = makeController(); + var disk = { + type: "physical", + fstype: "", + original: { + partition_table_type: null, + available_size: 10 * 1024 * 1024, + block_size: 1024 + } + }; + spyOn($scope, "isAllStorageDisabled").and.returnValue(false); + $scope.isSuperUser = function() { return false; }; + expect($scope.canAddPartition(disk)).toBe(false); + }); + + it("returns false if isAllStorageDisabled", function() { + var controller = makeController(); + var disk = { + type: "physical", + fstype: "", + original: { + partition_table_type: null, + available_size: 10 * 1024 * 1024, + block_size: 1024 + } + }; + spyOn($scope, "isAllStorageDisabled").and.returnValue(true); + $scope.isSuperUser = function() { return true; }; + expect($scope.canAddPartition(disk)).toBe(false); + }); + it("returns true otherwise", function() { var controller = makeController(); var disk = { @@ -1252,6 +1315,8 @@ block_size: 1024 } }; + spyOn($scope, "isAllStorageDisabled").and.returnValue(false); + $scope.isSuperUser = function() { return true; }; expect($scope.canAddPartition(disk)).toBe(true); }); }); @@ -1706,10 +1771,44 @@ used_size: 0 } }; + $scope.isSuperUser = function() { return true; }; + spyOn($scope, "isAllStorageDisabled").and.returnValue(false); expect($scope.canDelete(disk)).toBe(true); }); + it("returns false if not super user", function() { + var controller = makeController(); + var disk = { + type: "lvm-vg", + fstype: null, + has_partitions: false, + original: { + used_size: 0 + } + }; + $scope.isSuperUser = function() { return false; }; + spyOn($scope, "isAllStorageDisabled").and.returnValue(false); + + expect($scope.canDelete(disk)).toBe(false); + }); + + it("returns false if isAllStorageDisabled", function() { + var controller = makeController(); + var disk = { + type: "lvm-vg", + fstype: null, + has_partitions: false, + original: { + used_size: 0 + } + }; + $scope.isSuperUser = function() { return true; }; + spyOn($scope, "isAllStorageDisabled").and.returnValue(true); + + expect($scope.canDelete(disk)).toBe(false); + }); + it("returns false if volume group used", function() { var controller = makeController(); var disk = { @@ -1720,6 +1819,8 @@ used_size: makeInteger(100, 10000) } }; + $scope.isSuperUser = function() { return true; }; + spyOn($scope, "isAllStorageDisabled").and.returnValue(false); expect($scope.canDelete(disk)).toBe(false); }); @@ -1727,6 +1828,8 @@ it("returns true if fstype is null", function() { var controller = makeController(); var disk = { fstype: null, has_partitions: false }; + $scope.isSuperUser = function() { return true; }; + spyOn($scope, "isAllStorageDisabled").and.returnValue(false); expect($scope.canDelete(disk)).toBe(true); }); @@ -1734,6 +1837,8 @@ it("returns true if fstype is empty", function() { var controller = makeController(); var disk = { fstype: "", has_partitions: false }; + $scope.isSuperUser = function() { return true; }; + spyOn($scope, "isAllStorageDisabled").and.returnValue(false); expect($scope.canDelete(disk)).toBe(true); }); @@ -1741,6 +1846,8 @@ it("returns false if has_partitions is true", function() { var controller = makeController(); var disk = { fstype: "", has_partitions: true }; + $scope.isSuperUser = function() { return true; }; + spyOn($scope, "isAllStorageDisabled").and.returnValue(false); expect($scope.canDelete(disk)).toBe(false); }); @@ -1748,6 +1855,8 @@ it("returns false if fstype is not empty", function() { var controller = makeController(); var disk = { fstype: "ext4" }; + $scope.isSuperUser = function() { return true; }; + spyOn($scope, "isAllStorageDisabled").and.returnValue(false); expect($scope.canDelete(disk)).toBe(false); }); @@ -2377,6 +2486,8 @@ it("returns false for NONE", function() { var controller = makeController(); $scope.cachesetsMode = null; + $scope.isSuperUser = function() { return true; }; + spyOn($scope, "isAllStorageDisabled").and.returnValue(false); expect($scope.isCacheSetsDisabled()).toBe(false); }); @@ -2384,6 +2495,8 @@ it("returns false for SINGLE", function() { var controller = makeController(); $scope.cachesetsMode = "single"; + $scope.isSuperUser = function() { return true; }; + spyOn($scope, "isAllStorageDisabled").and.returnValue(false); expect($scope.isCacheSetsDisabled()).toBe(false); }); @@ -2391,13 +2504,35 @@ it("returns false for MULTI", function() { var controller = makeController(); $scope.cachesetsMode = "multi"; + $scope.isSuperUser = function() { return true; }; + spyOn($scope, "isAllStorageDisabled").and.returnValue(false); expect($scope.isCacheSetsDisabled()).toBe(false); }); + it("returns true for when not super user", function() { + var controller = makeController(); + $scope.cachesetsMode = "delete"; + $scope.isSuperUser = function() { return false; }; + spyOn($scope, "isAllStorageDisabled").and.returnValue(false); + + expect($scope.isCacheSetsDisabled()).toBe(true); + }); + + it("returns true for when isAllStorageDisabled", function() { + var controller = makeController(); + $scope.cachesetsMode = "delete"; + $scope.isSuperUser = function() { return true; }; + spyOn($scope, "isAllStorageDisabled").and.returnValue(true); + + expect($scope.isCacheSetsDisabled()).toBe(true); + }); + it("returns true for DELETE", function() { var controller = makeController(); $scope.cachesetsMode = "delete"; + $scope.isSuperUser = function() { return true; }; + spyOn($scope, "isAllStorageDisabled").and.returnValue(false); expect($scope.isCacheSetsDisabled()).toBe(true); }); @@ -2421,6 +2556,8 @@ it("returns true when not being used", function() { var controller = makeController(); var cacheset = { used_by: "" }; + $scope.isSuperUser = function() { return true; }; + spyOn($scope, "isAllStorageDisabled").and.returnValue(false); expect($scope.canDeleteCacheSet(cacheset)).toBe(true); }); @@ -2428,6 +2565,26 @@ it("returns false when being used", function() { var controller = makeController(); var cacheset = { used_by: "bcache0" }; + $scope.isSuperUser = function() { return true; }; + spyOn($scope, "isAllStorageDisabled").and.returnValue(false); + + expect($scope.canDeleteCacheSet(cacheset)).toBe(false); + }); + + it("returns false when not super user", function() { + var controller = makeController(); + var cacheset = { used_by: "" }; + $scope.isSuperUser = function() { return false; }; + spyOn($scope, "isAllStorageDisabled").and.returnValue(false); + + expect($scope.canDeleteCacheSet(cacheset)).toBe(false); + }); + + it("returns false when isAllStorageDisabled", function() { + var controller = makeController(); + var cacheset = { used_by: "" }; + $scope.isSuperUser = function() { return true; }; + spyOn($scope, "isAllStorageDisabled").and.returnValue(true); expect($scope.canDeleteCacheSet(cacheset)).toBe(false); }); @@ -2490,6 +2647,7 @@ it("returns false if isAvailableDisabled returns true", function() { var controller = makeController(); spyOn($scope, "isAvailableDisabled").and.returnValue(true); + $scope.isSuperUser = function() { return true; }; expect($scope.canCreateCacheSet()).toBe(false); }); @@ -2498,6 +2656,7 @@ var controller = makeController(); spyOn($scope, "isAvailableDisabled").and.returnValue(false); $scope.available = [ { $selected: true }, { $selected: true }]; + $scope.isSuperUser = function() { return true; }; expect($scope.canCreateCacheSet()).toBe(false); }); @@ -2511,6 +2670,7 @@ $selected: true } ]; + $scope.isSuperUser = function() { return true; }; expect($scope.canCreateCacheSet()).toBe(false); }); @@ -2525,6 +2685,21 @@ $selected: true } ]; + $scope.isSuperUser = function() { return true; }; + + expect($scope.canCreateCacheSet()).toBe(false); + }); + + it("returns false if not super user", function() { + var controller = makeController(); + spyOn($scope, "isAvailableDisabled").and.returnValue(false); + $scope.available = [ + { + fstype: null, + $selected: true + } + ]; + $scope.isSuperUser = function() { return false; }; expect($scope.canCreateCacheSet()).toBe(false); }); @@ -2538,6 +2713,7 @@ $selected: true } ]; + $scope.isSuperUser = function() { return true; }; expect($scope.canCreateCacheSet()).toBe(true); }); @@ -2584,6 +2760,7 @@ it("returns false when isAvailableDisabled is true", function() { var controller = makeController(); spyOn($scope, "isAvailableDisabled").and.returnValue(true); + $scope.isSuperUser = function() { return true; }; expect($scope.canCreateBcache()).toBe(false); }); @@ -2592,6 +2769,7 @@ var controller = makeController(); spyOn($scope, "isAvailableDisabled").and.returnValue(false); $scope.available = [ { $selected: true }, { $selected: true }]; + $scope.isSuperUser = function() { return true; }; expect($scope.canCreateBcache()).toBe(false); }); @@ -2606,6 +2784,7 @@ } ]; $scope.cachesets = [{}]; + $scope.isSuperUser = function() { return true; }; expect($scope.canCreateBcache()).toBe(false); }); @@ -2621,6 +2800,7 @@ } ]; $scope.cachesets = [{}]; + $scope.isSuperUser = function() { return true; }; expect($scope.canCreateBcache()).toBe(false); }); @@ -2636,6 +2816,23 @@ } ]; $scope.cachesets = []; + $scope.isSuperUser = function() { return true; }; + + expect($scope.canCreateBcache()).toBe(false); + }); + + it("returns false if not super user ", + function() { + var controller = makeController(); + spyOn($scope, "isAvailableDisabled").and.returnValue(false); + $scope.available = [ + { + fstype: null, + $selected: true + } + ]; + $scope.cachesets = [{}]; + $scope.isSuperUser = function() { return false; }; expect($scope.canCreateBcache()).toBe(false); }); @@ -2651,6 +2848,7 @@ } ]; $scope.cachesets = [{}]; + $scope.isSuperUser = function() { return true; }; expect($scope.canCreateBcache()).toBe(true); }); @@ -2915,6 +3113,7 @@ it("returns false isAvailableDisabled returns true", function() { var controller = makeController(); spyOn($scope, "isAvailableDisabled").and.returnValue(true); + $scope.isSuperUser = function() { return true; }; expect($scope.canCreateRAID()).toBe(false); }); @@ -2922,6 +3121,7 @@ var controller = makeController(); spyOn($scope, "isAvailableDisabled").and.returnValue(false); spyOn($scope, "getSelectedAvailable").and.returnValue([{}]); + $scope.isSuperUser = function() { return true; }; expect($scope.canCreateRAID()).toBe(false); }); @@ -2930,6 +3130,7 @@ spyOn($scope, "isAvailableDisabled").and.returnValue(false); spyOn($scope, "getSelectedAvailable").and.returnValue([{}, {}]); spyOn($scope, "hasUnmountedFilesystem").and.returnValue(true); + $scope.isSuperUser = function() { return true; }; expect($scope.canCreateRAID()).toBe(false); }); @@ -2945,6 +3146,16 @@ } ]); spyOn($scope, "hasUnmountedFilesystem").and.returnValue(false); + $scope.isSuperUser = function() { return true; }; + expect($scope.canCreateRAID()).toBe(false); + }); + + it("returns false if not super user", function() { + var controller = makeController(); + spyOn($scope, "isAvailableDisabled").and.returnValue(false); + spyOn($scope, "getSelectedAvailable").and.returnValue([{}, {}]); + spyOn($scope, "hasUnmountedFilesystem").and.returnValue(false); + $scope.isSuperUser = function() { return false; }; expect($scope.canCreateRAID()).toBe(false); }); @@ -2953,6 +3164,8 @@ spyOn($scope, "isAvailableDisabled").and.returnValue(false); spyOn($scope, "getSelectedAvailable").and.returnValue([{}, {}]); spyOn($scope, "hasUnmountedFilesystem").and.returnValue(false); + $scope.isSuperUser = function() { return true; }; + spyOn($scope, "isAllStorageDisabled").and.returnValue(false); expect($scope.canCreateRAID()).toBe(true); }); }); @@ -3596,6 +3809,7 @@ it("returns false isAvailableDisabled returns true", function() { var controller = makeController(); spyOn($scope, "isAvailableDisabled").and.returnValue(true); + $scope.isSuperUser = function() { return true; }; expect($scope.canCreateVolumeGroup()).toBe(false); }); @@ -3604,6 +3818,7 @@ spyOn($scope, "isAvailableDisabled").and.returnValue(false); spyOn($scope, "getSelectedAvailable").and.returnValue([{}]); spyOn($scope, "hasUnmountedFilesystem").and.returnValue(true); + $scope.isSuperUser = function() { return true; }; expect($scope.canCreateVolumeGroup()).toBe(false); }); @@ -3619,6 +3834,16 @@ } ]); spyOn($scope, "hasUnmountedFilesystem").and.returnValue(false); + $scope.isSuperUser = function() { return true; }; + expect($scope.canCreateVolumeGroup()).toBe(false); + }); + + it("returns false if not super user", function() { + var controller = makeController(); + spyOn($scope, "isAvailableDisabled").and.returnValue(false); + spyOn($scope, "getSelectedAvailable").and.returnValue([{}]); + spyOn($scope, "hasUnmountedFilesystem").and.returnValue(false); + $scope.isSuperUser = function() { return false; }; expect($scope.canCreateVolumeGroup()).toBe(false); }); @@ -3627,6 +3852,7 @@ spyOn($scope, "isAvailableDisabled").and.returnValue(false); spyOn($scope, "getSelectedAvailable").and.returnValue([{}]); spyOn($scope, "hasUnmountedFilesystem").and.returnValue(false); + $scope.isSuperUser = function() { return true; }; expect($scope.canCreateVolumeGroup()).toBe(true); }); }); @@ -4025,8 +4251,28 @@ })).toBe(false); }); + it("returns false when not super user", function() { + var controller = makeController(); + $scope.isSuperUser = function() { return false; }; + spyOn($scope, "isAllStorageDisabled").and.returnValue(false); + expect($scope.canEditTags({ + type: "physical" + })).toBe(false); + }); + + it("returns false when isAllStorageDisabled", function() { + var controller = makeController(); + $scope.isSuperUser = function() { return true; }; + spyOn($scope, "isAllStorageDisabled").and.returnValue(true); + expect($scope.canEditTags({ + type: "physical" + })).toBe(false); + }); + it("returns true for physical", function() { var controller = makeController(); + $scope.isSuperUser = function() { return true; }; + spyOn($scope, "isAllStorageDisabled").and.returnValue(false); expect($scope.canEditTags({ type: "physical" })).toBe(true); @@ -4034,6 +4280,8 @@ it("returns true for virtual", function() { var controller = makeController(); + $scope.isSuperUser = function() { return true; }; + spyOn($scope, "isAllStorageDisabled").and.returnValue(false); expect($scope.canEditTags({ type: "virtual" })).toBe(true); @@ -4095,4 +4343,60 @@ expect(disk.tags).toEqual(tags); }); }); + + describe("isAllStorageDisabled", function() { + + var RegionConnection, UserManager; + beforeEach(inject(function($injector) { + UsersManager = $injector.get("UsersManager"); + RegionConnection = $injector.get("RegionConnection"); + + // Mock buildSocket so an actual connection is not made. + webSocket = new MockWebSocket(); + spyOn(RegionConnection, "buildSocket").and.returnValue(webSocket); + })); + + it("false when status is Ready", function() { + var controller = makeController(); + $scope.node.status = "Ready"; + spyOn(UsersManager, "getAuthUser").and.returnValue( + { is_superuser: true }); + expect($scope.isAllStorageDisabled()).toBe(false); + }); + + it("false when status is Allocated", function() { + var controller = makeController(); + $scope.node.status = "Allocated"; + spyOn(UsersManager, "getAuthUser").and.returnValue( + { is_superuser: true }); + expect($scope.isAllStorageDisabled()).toBe(false); + }); + + it("false when Allocated and owned", function() { + var controller = makeController(); + var user = makeName("user"); + $scope.node.status = "Allocated"; + $scope.node.owner = user; + spyOn(UsersManager, "getAuthUser").and.returnValue( + { is_superuser: false, username: user }); + expect($scope.isAllStorageDisabled()).toBe(false); + }); + + it("true when not admin", function() { + var controller = makeController(); + $scope.node.status = "Allocated"; + $scope.node.owner = makeName("user"); + spyOn(UsersManager, "getAuthUser").and.returnValue( + { is_superuser: false, username: makeName("user") }); + expect($scope.isAllStorageDisabled()).toBe(true); + }); + + it("true otherwise", function() { + var controller = makeController(); + $scope.node.status = makeName("status"); + spyOn(UsersManager, "getAuthUser").and.returnValue( + { is_superuser: true }); + expect($scope.isAllStorageDisabled()).toBe(true); + }); + }); }); === modified file 'src/maasserver/static/partials/node-details.html' --- src/maasserver/static/partials/node-details.html 2015-11-01 00:22:00 +0000 +++ src/maasserver/static/partials/node-details.html 2015-11-03 04:58:42 +0000 @@ -652,6 +652,16 @@ +