mirror of
https://github.com/portainer/portainer.git
synced 2025-07-24 07:49:41 +02:00
feat(containers): disable edit container on security setting restricting regular users (#4111)
* feat(settings): add info about container edit disable * feat(settings): set security settings * feat(containers): hide recreate button when setting is enabled * feat(settings): rephrase security notice * fix(settings): save allowHostNamespaceForRegularUsers to state
This commit is contained in:
parent
1a3f77137a
commit
7539f09f98
5 changed files with 54 additions and 2 deletions
|
@ -21,6 +21,7 @@ angular.module('portainer.docker').controller('ContainerController', [
|
||||||
'ImageService',
|
'ImageService',
|
||||||
'HttpRequestHelper',
|
'HttpRequestHelper',
|
||||||
'Authentication',
|
'Authentication',
|
||||||
|
'StateManager',
|
||||||
function (
|
function (
|
||||||
$q,
|
$q,
|
||||||
$scope,
|
$scope,
|
||||||
|
@ -40,7 +41,8 @@ angular.module('portainer.docker').controller('ContainerController', [
|
||||||
RegistryService,
|
RegistryService,
|
||||||
ImageService,
|
ImageService,
|
||||||
HttpRequestHelper,
|
HttpRequestHelper,
|
||||||
Authentication
|
Authentication,
|
||||||
|
StateManager
|
||||||
) {
|
) {
|
||||||
$scope.activityTime = 0;
|
$scope.activityTime = 0;
|
||||||
$scope.portBindings = [];
|
$scope.portBindings = [];
|
||||||
|
@ -94,9 +96,24 @@ angular.module('portainer.docker').controller('ContainerController', [
|
||||||
const inSwarm = $scope.container.Config.Labels['com.docker.swarm.service.id'];
|
const inSwarm = $scope.container.Config.Labels['com.docker.swarm.service.id'];
|
||||||
const autoRemove = $scope.container.HostConfig.AutoRemove;
|
const autoRemove = $scope.container.HostConfig.AutoRemove;
|
||||||
const admin = Authentication.isAdmin();
|
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) => {
|
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) {
|
.catch(function error(err) {
|
||||||
|
|
|
@ -26,6 +26,7 @@ export function PublicSettingsViewModel(settings) {
|
||||||
this.AllowDeviceMappingForRegularUsers = settings.AllowDeviceMappingForRegularUsers;
|
this.AllowDeviceMappingForRegularUsers = settings.AllowDeviceMappingForRegularUsers;
|
||||||
this.AllowStackManagementForRegularUsers = settings.AllowStackManagementForRegularUsers;
|
this.AllowStackManagementForRegularUsers = settings.AllowStackManagementForRegularUsers;
|
||||||
this.AllowContainerCapabilitiesForRegularUsers = settings.AllowContainerCapabilitiesForRegularUsers;
|
this.AllowContainerCapabilitiesForRegularUsers = settings.AllowContainerCapabilitiesForRegularUsers;
|
||||||
|
this.AllowHostNamespaceForRegularUsers = settings.AllowHostNamespaceForRegularUsers;
|
||||||
this.AuthenticationMethod = settings.AuthenticationMethod;
|
this.AuthenticationMethod = settings.AuthenticationMethod;
|
||||||
this.EnableHostManagementFeatures = settings.EnableHostManagementFeatures;
|
this.EnableHostManagementFeatures = settings.EnableHostManagementFeatures;
|
||||||
this.EnableEdgeComputeFeatures = settings.EnableEdgeComputeFeatures;
|
this.EnableEdgeComputeFeatures = settings.EnableEdgeComputeFeatures;
|
||||||
|
|
|
@ -96,6 +96,16 @@ angular.module('portainer.app').factory('StateManager', [
|
||||||
LocalStorage.storeApplicationState(state.application);
|
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) {
|
function assignStateFromStatusAndSettings(status, settings) {
|
||||||
state.application.analytics = status.Analytics;
|
state.application.analytics = status.Analytics;
|
||||||
state.application.version = status.Version;
|
state.application.version = status.Version;
|
||||||
|
@ -107,6 +117,9 @@ angular.module('portainer.app').factory('StateManager', [
|
||||||
state.application.allowDeviceMappingForRegularUsers = settings.AllowDeviceMappingForRegularUsers;
|
state.application.allowDeviceMappingForRegularUsers = settings.AllowDeviceMappingForRegularUsers;
|
||||||
state.application.allowStackManagementForRegularUsers = settings.AllowStackManagementForRegularUsers;
|
state.application.allowStackManagementForRegularUsers = settings.AllowStackManagementForRegularUsers;
|
||||||
state.application.allowContainerCapabilitiesForRegularUsers = settings.AllowContainerCapabilitiesForRegularUsers;
|
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();
|
state.application.validity = moment().unix();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -149,6 +149,12 @@
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group" ng-if="isContainerEditDisabled()">
|
||||||
|
<span class="col-sm-12 text-muted small">
|
||||||
|
Note: The recreate/duplicate/edit feature is currently disabled (for non-admin users) by one or more security settings.
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
<!-- !security -->
|
<!-- !security -->
|
||||||
<!-- edge -->
|
<!-- edge -->
|
||||||
<div class="col-sm-12 form-section-title">
|
<div class="col-sm-12 form-section-title">
|
||||||
|
|
|
@ -38,6 +38,19 @@ angular.module('portainer.app').controller('SettingsController', [
|
||||||
disableContainerCapabilitiesForRegularUsers: false,
|
disableContainerCapabilitiesForRegularUsers: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$scope.isContainerEditDisabled = function isContainerEditDisabled() {
|
||||||
|
const {
|
||||||
|
restrictBindMounts,
|
||||||
|
restrictHostNamespaceForRegularUsers,
|
||||||
|
restrictPrivilegedMode,
|
||||||
|
disableDeviceMappingForRegularUsers,
|
||||||
|
disableContainerCapabilitiesForRegularUsers,
|
||||||
|
} = this.formValues;
|
||||||
|
return (
|
||||||
|
restrictBindMounts || restrictHostNamespaceForRegularUsers || restrictPrivilegedMode || disableDeviceMappingForRegularUsers || disableContainerCapabilitiesForRegularUsers
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
$scope.removeFilteredContainerLabel = function (index) {
|
$scope.removeFilteredContainerLabel = function (index) {
|
||||||
var settings = $scope.settings;
|
var settings = $scope.settings;
|
||||||
settings.BlackListedLabels.splice(index, 1);
|
settings.BlackListedLabels.splice(index, 1);
|
||||||
|
@ -90,6 +103,8 @@ angular.module('portainer.app').controller('SettingsController', [
|
||||||
StateManager.updateAllowDeviceMappingForRegularUsers(settings.AllowDeviceMappingForRegularUsers);
|
StateManager.updateAllowDeviceMappingForRegularUsers(settings.AllowDeviceMappingForRegularUsers);
|
||||||
StateManager.updateAllowStackManagementForRegularUsers(settings.AllowStackManagementForRegularUsers);
|
StateManager.updateAllowStackManagementForRegularUsers(settings.AllowStackManagementForRegularUsers);
|
||||||
StateManager.updateAllowContainerCapabilitiesForRegularUsers(settings.AllowContainerCapabilitiesForRegularUsers);
|
StateManager.updateAllowContainerCapabilitiesForRegularUsers(settings.AllowContainerCapabilitiesForRegularUsers);
|
||||||
|
StateManager.updateAllowPrivilegedModeForRegularUsers(settings.AllowPrivilegedModeForRegularUsers);
|
||||||
|
StateManager.updateAllowBindMountsForRegularUsers(settings.AllowBindMountsForRegularUsers);
|
||||||
$state.reload();
|
$state.reload();
|
||||||
})
|
})
|
||||||
.catch(function error(err) {
|
.catch(function error(err) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue