mirror of https://github.com/portainer/portainer
feat(settings): add a setting to disable privileged mode for non-admins (#1239)
parent
ca9d9b9a77
commit
0bdcff09f8
|
@ -0,0 +1,16 @@
|
|||
package bolt
|
||||
|
||||
func (m *Migrator) updateSettingsToVersion6() error {
|
||||
legacySettings, err := m.SettingsService.Settings()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
legacySettings.AllowPrivilegedModeForRegularUsers = true
|
||||
|
||||
err = m.SettingsService.StoreSettings(legacySettings)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -73,6 +73,14 @@ func (m *Migrator) Migrate() error {
|
|||
}
|
||||
}
|
||||
|
||||
// https://github.com/portainer/portainer/issues/1236
|
||||
if m.CurrentDBVersion < 6 {
|
||||
err := m.updateSettingsToVersion6()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
err := m.VersionService.StoreDBVersion(portainer.DBVersion)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -125,7 +125,8 @@ func initSettings(settingsService portainer.SettingsService, flags *portainer.CL
|
|||
portainer.LDAPSearchSettings{},
|
||||
},
|
||||
},
|
||||
AllowBindMountsForRegularUsers: true,
|
||||
AllowBindMountsForRegularUsers: true,
|
||||
AllowPrivilegedModeForRegularUsers: true,
|
||||
}
|
||||
|
||||
if *flags.Templates != "" {
|
||||
|
|
|
@ -45,20 +45,22 @@ func NewSettingsHandler(bouncer *security.RequestBouncer) *SettingsHandler {
|
|||
|
||||
type (
|
||||
publicSettingsResponse struct {
|
||||
LogoURL string `json:"LogoURL"`
|
||||
DisplayExternalContributors bool `json:"DisplayExternalContributors"`
|
||||
AuthenticationMethod portainer.AuthenticationMethod `json:"AuthenticationMethod"`
|
||||
AllowBindMountsForRegularUsers bool `json:"AllowBindMountsForRegularUsers"`
|
||||
LogoURL string `json:"LogoURL"`
|
||||
DisplayExternalContributors bool `json:"DisplayExternalContributors"`
|
||||
AuthenticationMethod portainer.AuthenticationMethod `json:"AuthenticationMethod"`
|
||||
AllowBindMountsForRegularUsers bool `json:"AllowBindMountsForRegularUsers"`
|
||||
AllowPrivilegedModeForRegularUsers bool `json:"AllowPrivilegedModeForRegularUsers"`
|
||||
}
|
||||
|
||||
putSettingsRequest struct {
|
||||
TemplatesURL string `valid:"required"`
|
||||
LogoURL string `valid:""`
|
||||
BlackListedLabels []portainer.Pair `valid:""`
|
||||
DisplayExternalContributors bool `valid:""`
|
||||
AuthenticationMethod int `valid:"required"`
|
||||
LDAPSettings portainer.LDAPSettings `valid:""`
|
||||
AllowBindMountsForRegularUsers bool `valid:""`
|
||||
TemplatesURL string `valid:"required"`
|
||||
LogoURL string `valid:""`
|
||||
BlackListedLabels []portainer.Pair `valid:""`
|
||||
DisplayExternalContributors bool `valid:""`
|
||||
AuthenticationMethod int `valid:"required"`
|
||||
LDAPSettings portainer.LDAPSettings `valid:""`
|
||||
AllowBindMountsForRegularUsers bool `valid:""`
|
||||
AllowPrivilegedModeForRegularUsers bool `valid:""`
|
||||
}
|
||||
|
||||
putSettingsLDAPCheckRequest struct {
|
||||
|
@ -87,10 +89,11 @@ func (handler *SettingsHandler) handleGetPublicSettings(w http.ResponseWriter, r
|
|||
}
|
||||
|
||||
publicSettings := &publicSettingsResponse{
|
||||
LogoURL: settings.LogoURL,
|
||||
DisplayExternalContributors: settings.DisplayExternalContributors,
|
||||
AuthenticationMethod: settings.AuthenticationMethod,
|
||||
AllowBindMountsForRegularUsers: settings.AllowBindMountsForRegularUsers,
|
||||
LogoURL: settings.LogoURL,
|
||||
DisplayExternalContributors: settings.DisplayExternalContributors,
|
||||
AuthenticationMethod: settings.AuthenticationMethod,
|
||||
AllowBindMountsForRegularUsers: settings.AllowBindMountsForRegularUsers,
|
||||
AllowPrivilegedModeForRegularUsers: settings.AllowPrivilegedModeForRegularUsers,
|
||||
}
|
||||
|
||||
encodeJSON(w, publicSettings, handler.Logger)
|
||||
|
@ -112,12 +115,13 @@ func (handler *SettingsHandler) handlePutSettings(w http.ResponseWriter, r *http
|
|||
}
|
||||
|
||||
settings := &portainer.Settings{
|
||||
TemplatesURL: req.TemplatesURL,
|
||||
LogoURL: req.LogoURL,
|
||||
BlackListedLabels: req.BlackListedLabels,
|
||||
DisplayExternalContributors: req.DisplayExternalContributors,
|
||||
LDAPSettings: req.LDAPSettings,
|
||||
AllowBindMountsForRegularUsers: req.AllowBindMountsForRegularUsers,
|
||||
TemplatesURL: req.TemplatesURL,
|
||||
LogoURL: req.LogoURL,
|
||||
BlackListedLabels: req.BlackListedLabels,
|
||||
DisplayExternalContributors: req.DisplayExternalContributors,
|
||||
LDAPSettings: req.LDAPSettings,
|
||||
AllowBindMountsForRegularUsers: req.AllowBindMountsForRegularUsers,
|
||||
AllowPrivilegedModeForRegularUsers: req.AllowPrivilegedModeForRegularUsers,
|
||||
}
|
||||
|
||||
if req.AuthenticationMethod == 1 {
|
||||
|
|
|
@ -70,13 +70,14 @@ type (
|
|||
|
||||
// Settings represents the application settings.
|
||||
Settings struct {
|
||||
TemplatesURL string `json:"TemplatesURL"`
|
||||
LogoURL string `json:"LogoURL"`
|
||||
BlackListedLabels []Pair `json:"BlackListedLabels"`
|
||||
DisplayExternalContributors bool `json:"DisplayExternalContributors"`
|
||||
AuthenticationMethod AuthenticationMethod `json:"AuthenticationMethod"`
|
||||
LDAPSettings LDAPSettings `json:"LDAPSettings"`
|
||||
AllowBindMountsForRegularUsers bool `json:"AllowBindMountsForRegularUsers"`
|
||||
TemplatesURL string `json:"TemplatesURL"`
|
||||
LogoURL string `json:"LogoURL"`
|
||||
BlackListedLabels []Pair `json:"BlackListedLabels"`
|
||||
DisplayExternalContributors bool `json:"DisplayExternalContributors"`
|
||||
AuthenticationMethod AuthenticationMethod `json:"AuthenticationMethod"`
|
||||
LDAPSettings LDAPSettings `json:"LDAPSettings"`
|
||||
AllowBindMountsForRegularUsers bool `json:"AllowBindMountsForRegularUsers"`
|
||||
AllowPrivilegedModeForRegularUsers bool `json:"AllowPrivilegedModeForRegularUsers"`
|
||||
}
|
||||
|
||||
// User represents a user account.
|
||||
|
@ -349,7 +350,7 @@ const (
|
|||
// APIVersion is the version number of the Portainer API.
|
||||
APIVersion = "1.14.2"
|
||||
// DBVersion is the version number of the Portainer database.
|
||||
DBVersion = 5
|
||||
DBVersion = 6
|
||||
// DefaultTemplatesURL represents the default URL for the templates definitions.
|
||||
DefaultTemplatesURL = "https://raw.githubusercontent.com/portainer/templates/master/templates.json"
|
||||
)
|
||||
|
|
|
@ -485,6 +485,7 @@ function ($q, $scope, $state, $transition$, $filter, Container, ContainerHelper,
|
|||
SettingsService.publicSettings()
|
||||
.then(function success(data) {
|
||||
$scope.allowBindMounts = data.AllowBindMountsForRegularUsers;
|
||||
$scope.allowPrivilegedMode = data.AllowPrivilegedModeForRegularUsers;
|
||||
})
|
||||
.catch(function error(err) {
|
||||
Notifications.error('Failure', err, 'Unable to retrieve application settings');
|
||||
|
|
|
@ -470,13 +470,13 @@
|
|||
<div class="tab-pane" id="runtime">
|
||||
<form class="form-horizontal" style="margin-top: 15px;">
|
||||
<!-- privileged-mode -->
|
||||
<div class="form-group">
|
||||
<div class="form-group" ng-if="isAdmin || allowPrivilegedMode">
|
||||
<div class="col-sm-12">
|
||||
<label for="ownership" class="control-label text-left">
|
||||
<label for="privileged_mode" class="control-label text-left">
|
||||
Privileged mode
|
||||
</label>
|
||||
<label class="switch" style="margin-left: 20px;">
|
||||
<input type="checkbox" ng-model="config.HostConfig.Privileged"><i></i>
|
||||
<input type="checkbox" name="privileged_mode" ng-model="config.HostConfig.Privileged"><i></i>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -26,6 +26,17 @@
|
|||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12">
|
||||
<label for="toggle_allowbindmounts" class="control-label text-left">
|
||||
Disable privileged mode for non-administrators
|
||||
<portainer-tooltip position="bottom" message="When enabled, regular users will not be able to use privileged mode when creating containers."></portainer-tooltip>
|
||||
</label>
|
||||
<label class="switch" style="margin-left: 20px;">
|
||||
<input type="checkbox" name="toggle_allowbindmounts" ng-model="formValues.restrictPrivilegedMode"><i></i>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<!-- security -->
|
||||
<!-- logo -->
|
||||
<div class="col-sm-12 form-section-title">
|
||||
|
|
|
@ -7,6 +7,7 @@ function ($scope, $state, Notifications, SettingsService, StateManager, DEFAULT_
|
|||
customTemplates: false,
|
||||
externalContributions: false,
|
||||
restrictBindMounts: false,
|
||||
restrictPrivilegedMode: false,
|
||||
labelName: '',
|
||||
labelValue: ''
|
||||
};
|
||||
|
@ -41,6 +42,7 @@ function ($scope, $state, Notifications, SettingsService, StateManager, DEFAULT_
|
|||
}
|
||||
settings.DisplayExternalContributors = !$scope.formValues.externalContributions;
|
||||
settings.AllowBindMountsForRegularUsers = !$scope.formValues.restrictBindMounts;
|
||||
settings.AllowPrivilegedModeForRegularUsers = !$scope.formValues.restrictPrivilegedMode;
|
||||
|
||||
updateSettings(settings, false);
|
||||
};
|
||||
|
@ -84,6 +86,7 @@ function ($scope, $state, Notifications, SettingsService, StateManager, DEFAULT_
|
|||
}
|
||||
$scope.formValues.externalContributions = !settings.DisplayExternalContributors;
|
||||
$scope.formValues.restrictBindMounts = !settings.AllowBindMountsForRegularUsers;
|
||||
$scope.formValues.restrictPrivilegedMode = !settings.AllowPrivilegedModeForRegularUsers;
|
||||
})
|
||||
.catch(function error(err) {
|
||||
Notifications.error('Failure', err, 'Unable to retrieve application settings');
|
||||
|
|
|
@ -6,4 +6,5 @@ function SettingsViewModel(data) {
|
|||
this.AuthenticationMethod = data.AuthenticationMethod;
|
||||
this.LDAPSettings = data.LDAPSettings;
|
||||
this.AllowBindMountsForRegularUsers = data.AllowBindMountsForRegularUsers;
|
||||
this.AllowPrivilegedModeForRegularUsers = data.AllowPrivilegedModeForRegularUsers;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue