feat(settings): add setting to disable device mapping for regular users (#4017)
* feat(settings): introduce device mapping service * feat(containers): hide devices field when setting is on * feat(containers): prevent passing of devices when not allowed * feat(stacks): prevent non admin from device mapping * feat(stacks): disallow swarm stack creation for user * refactor(settings): replace disableDeviceMapping with allow * fix(stacks): remove check for disable device mappings from swarm * feat(settings): rename field to disable * feat(settings): supply default value for disableDeviceMapping * feat(container): check for endpoint admin
This commit is contained in:
@@ -30,6 +30,7 @@ angular.module('portainer.docker').controller('CreateContainerController', [
|
||||
'SettingsService',
|
||||
'PluginService',
|
||||
'HttpRequestHelper',
|
||||
'ExtensionService',
|
||||
function (
|
||||
$q,
|
||||
$scope,
|
||||
@@ -55,7 +56,8 @@ angular.module('portainer.docker').controller('CreateContainerController', [
|
||||
SystemService,
|
||||
SettingsService,
|
||||
PluginService,
|
||||
HttpRequestHelper
|
||||
HttpRequestHelper,
|
||||
ExtensionService
|
||||
) {
|
||||
$scope.create = create;
|
||||
|
||||
@@ -603,7 +605,7 @@ angular.module('portainer.docker').controller('CreateContainerController', [
|
||||
});
|
||||
}
|
||||
|
||||
function initView() {
|
||||
async function initView() {
|
||||
var nodeName = $transition$.params().nodeName;
|
||||
$scope.formValues.NodeName = nodeName;
|
||||
HttpRequestHelper.setPortainerAgentTargetHeader(nodeName);
|
||||
@@ -682,6 +684,7 @@ angular.module('portainer.docker').controller('CreateContainerController', [
|
||||
});
|
||||
|
||||
$scope.isAdmin = Authentication.isAdmin();
|
||||
$scope.showDeviceMapping = await shouldShowDevices();
|
||||
}
|
||||
|
||||
function validateForm(accessControlData, isAdmin) {
|
||||
@@ -894,6 +897,19 @@ angular.module('portainer.docker').controller('CreateContainerController', [
|
||||
}
|
||||
}
|
||||
|
||||
async function shouldShowDevices() {
|
||||
const isAdmin = !$scope.applicationState.application.authentication || Authentication.isAdmin();
|
||||
const { allowDeviceMappingForRegularUsers } = $scope.applicationState.application;
|
||||
|
||||
if (isAdmin || allowDeviceMappingForRegularUsers) {
|
||||
return true;
|
||||
}
|
||||
const rbacEnabled = await ExtensionService.extensionEnabled(ExtensionService.EXTENSIONS.RBAC);
|
||||
if (rbacEnabled) {
|
||||
return Authentication.hasAuthorizations(['EndpointResourcesAccess']);
|
||||
}
|
||||
}
|
||||
|
||||
initView();
|
||||
},
|
||||
]);
|
||||
|
||||
@@ -629,7 +629,7 @@
|
||||
</form>
|
||||
<form class="form-horizontal" style="margin-top: 15px;">
|
||||
<!-- devices -->
|
||||
<div class="form-group">
|
||||
<div ng-if="showDeviceMapping" class="form-group">
|
||||
<div class="col-sm-12" style="margin-top: 5px;">
|
||||
<label class="control-label text-left">Devices</label>
|
||||
<span class="label label-default interactive" style="margin-left: 10px;" ng-click="addDevice()">
|
||||
|
||||
@@ -15,6 +15,7 @@ export function SettingsViewModel(data) {
|
||||
this.EnableEdgeComputeFeatures = data.EnableEdgeComputeFeatures;
|
||||
this.DisableStackManagementForRegularUsers = data.DisableStackManagementForRegularUsers;
|
||||
this.AllowHostNamespaceForRegularUsers = data.AllowHostNamespaceForRegularUsers;
|
||||
this.AllowDeviceMappingForRegularUsers = data.AllowDeviceMappingForRegularUsers;
|
||||
}
|
||||
|
||||
export function PublicSettingsViewModel(settings) {
|
||||
@@ -28,6 +29,7 @@ export function PublicSettingsViewModel(settings) {
|
||||
this.LogoURL = settings.LogoURL;
|
||||
this.OAuthLoginURI = settings.OAuthLoginURI;
|
||||
this.DisableStackManagementForRegularUsers = settings.DisableStackManagementForRegularUsers;
|
||||
this.AllowDeviceMappingForRegularUsers = settings.AllowDeviceMappingForRegularUsers;
|
||||
}
|
||||
|
||||
export function LDAPSettingsViewModel(data) {
|
||||
|
||||
@@ -81,6 +81,11 @@ angular.module('portainer.app').factory('StateManager', [
|
||||
LocalStorage.storeApplicationState(state.application);
|
||||
};
|
||||
|
||||
manager.updateAllowDeviceMappingForRegularUsers = function updateAllowDeviceMappingForRegularUsers(allowDeviceMappingForRegularUsers) {
|
||||
state.application.allowDeviceMappingForRegularUsers = allowDeviceMappingForRegularUsers;
|
||||
LocalStorage.storeApplicationState(state.application);
|
||||
};
|
||||
|
||||
manager.updateAllowHostNamespaceForRegularUsers = function (allowHostNamespaceForRegularUsers) {
|
||||
state.application.allowHostNamespaceForRegularUsers = allowHostNamespaceForRegularUsers;
|
||||
LocalStorage.storeApplicationState(state.application);
|
||||
@@ -98,6 +103,7 @@ angular.module('portainer.app').factory('StateManager', [
|
||||
state.application.enableVolumeBrowserForNonAdminUsers = settings.AllowVolumeBrowserForRegularUsers;
|
||||
state.application.enableEdgeComputeFeatures = settings.EnableEdgeComputeFeatures;
|
||||
state.application.disableStackManagementForRegularUsers = settings.DisableStackManagementForRegularUsers;
|
||||
state.application.allowDeviceMappingForRegularUsers = settings.AllowDeviceMappingForRegularUsers;
|
||||
state.application.validity = moment().unix();
|
||||
}
|
||||
|
||||
|
||||
@@ -141,6 +141,17 @@
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12">
|
||||
<label for="toggle_disableDeviceMappingForRegularUsers" class="control-label text-left">
|
||||
Disable device mappings for non-administrators
|
||||
</label>
|
||||
<label class="switch" style="margin-left: 20px;">
|
||||
<input type="checkbox" name="toggle_disableDeviceMappingForRegularUsers" ng-model="formValues.disableDeviceMappingForRegularUsers" /><i></i>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<!-- !security -->
|
||||
<!-- edge -->
|
||||
<div class="col-sm-12 form-section-title">
|
||||
|
||||
@@ -35,6 +35,7 @@ angular.module('portainer.app').controller('SettingsController', [
|
||||
enableEdgeComputeFeatures: false,
|
||||
disableStackManagementForRegularUsers: false,
|
||||
restrictHostNamespaceForRegularUsers: false,
|
||||
allowDeviceMappingForRegularUsers: false,
|
||||
};
|
||||
|
||||
$scope.removeFilteredContainerLabel = function (index) {
|
||||
@@ -73,6 +74,7 @@ angular.module('portainer.app').controller('SettingsController', [
|
||||
settings.EnableEdgeComputeFeatures = $scope.formValues.enableEdgeComputeFeatures;
|
||||
settings.DisableStackManagementForRegularUsers = $scope.formValues.disableStackManagementForRegularUsers;
|
||||
settings.AllowHostNamespaceForRegularUsers = !$scope.formValues.restrictHostNamespaceForRegularUsers;
|
||||
settings.AllowDeviceMappingForRegularUsers = !$scope.formValues.disableDeviceMappingForRegularUsers;
|
||||
|
||||
$scope.state.actionInProgress = true;
|
||||
updateSettings(settings);
|
||||
@@ -89,6 +91,7 @@ angular.module('portainer.app').controller('SettingsController', [
|
||||
StateManager.updateEnableEdgeComputeFeatures(settings.EnableEdgeComputeFeatures);
|
||||
StateManager.updateDisableStackManagementForRegularUsers(settings.DisableStackManagementForRegularUsers);
|
||||
StateManager.updateAllowHostNamespaceForRegularUsers(settings.AllowHostNamespaceForRegularUsers);
|
||||
StateManager.updateAllowDeviceMappingForRegularUsers(settings.AllowDeviceMappingForRegularUsers);
|
||||
$state.reload();
|
||||
})
|
||||
.catch(function error(err) {
|
||||
@@ -117,6 +120,7 @@ angular.module('portainer.app').controller('SettingsController', [
|
||||
$scope.formValues.enableEdgeComputeFeatures = settings.EnableEdgeComputeFeatures;
|
||||
$scope.formValues.disableStackManagementForRegularUsers = settings.DisableStackManagementForRegularUsers;
|
||||
$scope.formValues.restrictHostNamespaceForRegularUsers = !settings.AllowHostNamespaceForRegularUsers;
|
||||
$scope.formValues.disableDeviceMappingForRegularUsers = !settings.AllowDeviceMappingForRegularUsers;
|
||||
})
|
||||
.catch(function error(err) {
|
||||
Notifications.error('Failure', err, 'Unable to retrieve application settings');
|
||||
|
||||
Reference in New Issue
Block a user