diff --git a/app/docker/views/containers/edit/containerController.js b/app/docker/views/containers/edit/containerController.js index 6528669f1..aee0f07f1 100644 --- a/app/docker/views/containers/edit/containerController.js +++ b/app/docker/views/containers/edit/containerController.js @@ -21,6 +21,7 @@ angular.module('portainer.docker').controller('ContainerController', [ 'ImageService', 'HttpRequestHelper', 'Authentication', + 'StateManager', function ( $q, $scope, @@ -40,7 +41,8 @@ angular.module('portainer.docker').controller('ContainerController', [ RegistryService, ImageService, HttpRequestHelper, - Authentication + Authentication, + StateManager ) { $scope.activityTime = 0; $scope.portBindings = []; @@ -94,9 +96,24 @@ angular.module('portainer.docker').controller('ContainerController', [ const inSwarm = $scope.container.Config.Labels['com.docker.swarm.service.id']; const autoRemove = $scope.container.HostConfig.AutoRemove; const admin = Authentication.isAdmin(); + const appState = StateManager.getState(); + const { + allowContainerCapabilitiesForRegularUsers, + allowHostNamespaceForRegularUsers, + allowDeviceMappingForRegularUsers, + allowBindMountsForRegularUsers, + allowPrivilegedModeForRegularUsers, + } = appState.application; + + const settingRestrictsRegularUsers = + !allowContainerCapabilitiesForRegularUsers || + !allowBindMountsForRegularUsers || + !allowDeviceMappingForRegularUsers || + !allowHostNamespaceForRegularUsers || + !allowPrivilegedModeForRegularUsers; ExtensionService.extensionEnabled(ExtensionService.EXTENSIONS.RBAC).then((rbacEnabled) => { - $scope.displayRecreateButton = !inSwarm && !autoRemove && (rbacEnabled ? admin : true); + $scope.displayRecreateButton = !inSwarm && !autoRemove && (settingRestrictsRegularUsers || rbacEnabled ? admin : true); }); }) .catch(function error(err) { diff --git a/app/portainer/models/settings.js b/app/portainer/models/settings.js index bdd6c35a5..bec5e7894 100644 --- a/app/portainer/models/settings.js +++ b/app/portainer/models/settings.js @@ -26,6 +26,7 @@ export function PublicSettingsViewModel(settings) { this.AllowDeviceMappingForRegularUsers = settings.AllowDeviceMappingForRegularUsers; this.AllowStackManagementForRegularUsers = settings.AllowStackManagementForRegularUsers; this.AllowContainerCapabilitiesForRegularUsers = settings.AllowContainerCapabilitiesForRegularUsers; + this.AllowHostNamespaceForRegularUsers = settings.AllowHostNamespaceForRegularUsers; this.AuthenticationMethod = settings.AuthenticationMethod; this.EnableHostManagementFeatures = settings.EnableHostManagementFeatures; this.EnableEdgeComputeFeatures = settings.EnableEdgeComputeFeatures; diff --git a/app/portainer/services/stateManager.js b/app/portainer/services/stateManager.js index dcfdc36a6..7b28dfc86 100644 --- a/app/portainer/services/stateManager.js +++ b/app/portainer/services/stateManager.js @@ -96,6 +96,16 @@ angular.module('portainer.app').factory('StateManager', [ LocalStorage.storeApplicationState(state.application); }; + manager.updateAllowBindMountsForRegularUsers = function updateAllowBindMountsForRegularUsers(allowBindMountsForRegularUsers) { + state.application.allowBindMountsForRegularUsers = allowBindMountsForRegularUsers; + LocalStorage.storeApplicationState(state.application); + }; + + manager.updateAllowPrivilegedModeForRegularUsers = function (AllowPrivilegedModeForRegularUsers) { + state.application.allowPrivilegedModeForRegularUsers = AllowPrivilegedModeForRegularUsers; + LocalStorage.storeApplicationState(state.application); + }; + function assignStateFromStatusAndSettings(status, settings) { state.application.analytics = status.Analytics; state.application.version = status.Version; @@ -107,6 +117,9 @@ angular.module('portainer.app').factory('StateManager', [ state.application.allowDeviceMappingForRegularUsers = settings.AllowDeviceMappingForRegularUsers; state.application.allowStackManagementForRegularUsers = settings.AllowStackManagementForRegularUsers; state.application.allowContainerCapabilitiesForRegularUsers = settings.AllowContainerCapabilitiesForRegularUsers; + state.application.allowBindMountsForRegularUsers = settings.AllowBindMountsForRegularUsers; + state.application.allowPrivilegedModeForRegularUsers = settings.AllowPrivilegedModeForRegularUsers; + state.application.allowHostNamespaceForRegularUsers = settings.AllowHostNamespaceForRegularUsers; state.application.validity = moment().unix(); } diff --git a/app/portainer/views/settings/settings.html b/app/portainer/views/settings/settings.html index 183fd0c90..b9e3c97cf 100644 --- a/app/portainer/views/settings/settings.html +++ b/app/portainer/views/settings/settings.html @@ -149,6 +149,12 @@ + +
+ + Note: The recreate/duplicate/edit feature is currently disabled (for non-admin users) by one or more security settings. + +
diff --git a/app/portainer/views/settings/settingsController.js b/app/portainer/views/settings/settingsController.js index 8bdfcb420..09e6f862a 100644 --- a/app/portainer/views/settings/settingsController.js +++ b/app/portainer/views/settings/settingsController.js @@ -38,6 +38,19 @@ angular.module('portainer.app').controller('SettingsController', [ disableContainerCapabilitiesForRegularUsers: false, }; + $scope.isContainerEditDisabled = function isContainerEditDisabled() { + const { + restrictBindMounts, + restrictHostNamespaceForRegularUsers, + restrictPrivilegedMode, + disableDeviceMappingForRegularUsers, + disableContainerCapabilitiesForRegularUsers, + } = this.formValues; + return ( + restrictBindMounts || restrictHostNamespaceForRegularUsers || restrictPrivilegedMode || disableDeviceMappingForRegularUsers || disableContainerCapabilitiesForRegularUsers + ); + }; + $scope.removeFilteredContainerLabel = function (index) { var settings = $scope.settings; settings.BlackListedLabels.splice(index, 1); @@ -90,6 +103,8 @@ angular.module('portainer.app').controller('SettingsController', [ StateManager.updateAllowDeviceMappingForRegularUsers(settings.AllowDeviceMappingForRegularUsers); StateManager.updateAllowStackManagementForRegularUsers(settings.AllowStackManagementForRegularUsers); StateManager.updateAllowContainerCapabilitiesForRegularUsers(settings.AllowContainerCapabilitiesForRegularUsers); + StateManager.updateAllowPrivilegedModeForRegularUsers(settings.AllowPrivilegedModeForRegularUsers); + StateManager.updateAllowBindMountsForRegularUsers(settings.AllowBindMountsForRegularUsers); $state.reload(); }) .catch(function error(err) {