1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-07-24 15:59:41 +02:00

feat(settings): add a setting to disable privileged mode for non-admins (#1239)

This commit is contained in:
Anthony Lapenna 2017-09-27 09:26:04 +02:00 committed by GitHub
parent ca9d9b9a77
commit 0bdcff09f8
10 changed files with 79 additions and 33 deletions

View file

@ -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
}

View file

@ -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) err := m.VersionService.StoreDBVersion(portainer.DBVersion)
if err != nil { if err != nil {
return err return err

View file

@ -125,7 +125,8 @@ func initSettings(settingsService portainer.SettingsService, flags *portainer.CL
portainer.LDAPSearchSettings{}, portainer.LDAPSearchSettings{},
}, },
}, },
AllowBindMountsForRegularUsers: true, AllowBindMountsForRegularUsers: true,
AllowPrivilegedModeForRegularUsers: true,
} }
if *flags.Templates != "" { if *flags.Templates != "" {

View file

@ -45,20 +45,22 @@ func NewSettingsHandler(bouncer *security.RequestBouncer) *SettingsHandler {
type ( type (
publicSettingsResponse struct { publicSettingsResponse struct {
LogoURL string `json:"LogoURL"` LogoURL string `json:"LogoURL"`
DisplayExternalContributors bool `json:"DisplayExternalContributors"` DisplayExternalContributors bool `json:"DisplayExternalContributors"`
AuthenticationMethod portainer.AuthenticationMethod `json:"AuthenticationMethod"` AuthenticationMethod portainer.AuthenticationMethod `json:"AuthenticationMethod"`
AllowBindMountsForRegularUsers bool `json:"AllowBindMountsForRegularUsers"` AllowBindMountsForRegularUsers bool `json:"AllowBindMountsForRegularUsers"`
AllowPrivilegedModeForRegularUsers bool `json:"AllowPrivilegedModeForRegularUsers"`
} }
putSettingsRequest struct { putSettingsRequest struct {
TemplatesURL string `valid:"required"` TemplatesURL string `valid:"required"`
LogoURL string `valid:""` LogoURL string `valid:""`
BlackListedLabels []portainer.Pair `valid:""` BlackListedLabels []portainer.Pair `valid:""`
DisplayExternalContributors bool `valid:""` DisplayExternalContributors bool `valid:""`
AuthenticationMethod int `valid:"required"` AuthenticationMethod int `valid:"required"`
LDAPSettings portainer.LDAPSettings `valid:""` LDAPSettings portainer.LDAPSettings `valid:""`
AllowBindMountsForRegularUsers bool `valid:""` AllowBindMountsForRegularUsers bool `valid:""`
AllowPrivilegedModeForRegularUsers bool `valid:""`
} }
putSettingsLDAPCheckRequest struct { putSettingsLDAPCheckRequest struct {
@ -87,10 +89,11 @@ func (handler *SettingsHandler) handleGetPublicSettings(w http.ResponseWriter, r
} }
publicSettings := &publicSettingsResponse{ publicSettings := &publicSettingsResponse{
LogoURL: settings.LogoURL, LogoURL: settings.LogoURL,
DisplayExternalContributors: settings.DisplayExternalContributors, DisplayExternalContributors: settings.DisplayExternalContributors,
AuthenticationMethod: settings.AuthenticationMethod, AuthenticationMethod: settings.AuthenticationMethod,
AllowBindMountsForRegularUsers: settings.AllowBindMountsForRegularUsers, AllowBindMountsForRegularUsers: settings.AllowBindMountsForRegularUsers,
AllowPrivilegedModeForRegularUsers: settings.AllowPrivilegedModeForRegularUsers,
} }
encodeJSON(w, publicSettings, handler.Logger) encodeJSON(w, publicSettings, handler.Logger)
@ -112,12 +115,13 @@ func (handler *SettingsHandler) handlePutSettings(w http.ResponseWriter, r *http
} }
settings := &portainer.Settings{ settings := &portainer.Settings{
TemplatesURL: req.TemplatesURL, TemplatesURL: req.TemplatesURL,
LogoURL: req.LogoURL, LogoURL: req.LogoURL,
BlackListedLabels: req.BlackListedLabels, BlackListedLabels: req.BlackListedLabels,
DisplayExternalContributors: req.DisplayExternalContributors, DisplayExternalContributors: req.DisplayExternalContributors,
LDAPSettings: req.LDAPSettings, LDAPSettings: req.LDAPSettings,
AllowBindMountsForRegularUsers: req.AllowBindMountsForRegularUsers, AllowBindMountsForRegularUsers: req.AllowBindMountsForRegularUsers,
AllowPrivilegedModeForRegularUsers: req.AllowPrivilegedModeForRegularUsers,
} }
if req.AuthenticationMethod == 1 { if req.AuthenticationMethod == 1 {

View file

@ -70,13 +70,14 @@ type (
// Settings represents the application settings. // Settings represents the application settings.
Settings struct { Settings struct {
TemplatesURL string `json:"TemplatesURL"` TemplatesURL string `json:"TemplatesURL"`
LogoURL string `json:"LogoURL"` LogoURL string `json:"LogoURL"`
BlackListedLabels []Pair `json:"BlackListedLabels"` BlackListedLabels []Pair `json:"BlackListedLabels"`
DisplayExternalContributors bool `json:"DisplayExternalContributors"` DisplayExternalContributors bool `json:"DisplayExternalContributors"`
AuthenticationMethod AuthenticationMethod `json:"AuthenticationMethod"` AuthenticationMethod AuthenticationMethod `json:"AuthenticationMethod"`
LDAPSettings LDAPSettings `json:"LDAPSettings"` LDAPSettings LDAPSettings `json:"LDAPSettings"`
AllowBindMountsForRegularUsers bool `json:"AllowBindMountsForRegularUsers"` AllowBindMountsForRegularUsers bool `json:"AllowBindMountsForRegularUsers"`
AllowPrivilegedModeForRegularUsers bool `json:"AllowPrivilegedModeForRegularUsers"`
} }
// User represents a user account. // User represents a user account.
@ -349,7 +350,7 @@ const (
// APIVersion is the version number of the Portainer API. // APIVersion is the version number of the Portainer API.
APIVersion = "1.14.2" APIVersion = "1.14.2"
// DBVersion is the version number of the Portainer database. // DBVersion is the version number of the Portainer database.
DBVersion = 5 DBVersion = 6
// DefaultTemplatesURL represents the default URL for the templates definitions. // DefaultTemplatesURL represents the default URL for the templates definitions.
DefaultTemplatesURL = "https://raw.githubusercontent.com/portainer/templates/master/templates.json" DefaultTemplatesURL = "https://raw.githubusercontent.com/portainer/templates/master/templates.json"
) )

View file

@ -485,6 +485,7 @@ function ($q, $scope, $state, $transition$, $filter, Container, ContainerHelper,
SettingsService.publicSettings() SettingsService.publicSettings()
.then(function success(data) { .then(function success(data) {
$scope.allowBindMounts = data.AllowBindMountsForRegularUsers; $scope.allowBindMounts = data.AllowBindMountsForRegularUsers;
$scope.allowPrivilegedMode = data.AllowPrivilegedModeForRegularUsers;
}) })
.catch(function error(err) { .catch(function error(err) {
Notifications.error('Failure', err, 'Unable to retrieve application settings'); Notifications.error('Failure', err, 'Unable to retrieve application settings');

View file

@ -470,13 +470,13 @@
<div class="tab-pane" id="runtime"> <div class="tab-pane" id="runtime">
<form class="form-horizontal" style="margin-top: 15px;"> <form class="form-horizontal" style="margin-top: 15px;">
<!-- privileged-mode --> <!-- privileged-mode -->
<div class="form-group"> <div class="form-group" ng-if="isAdmin || allowPrivilegedMode">
<div class="col-sm-12"> <div class="col-sm-12">
<label for="ownership" class="control-label text-left"> <label for="privileged_mode" class="control-label text-left">
Privileged mode Privileged mode
</label> </label>
<label class="switch" style="margin-left: 20px;"> <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> </label>
</div> </div>
</div> </div>

View file

@ -26,6 +26,17 @@
</label> </label>
</div> </div>
</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 --> <!-- security -->
<!-- logo --> <!-- logo -->
<div class="col-sm-12 form-section-title"> <div class="col-sm-12 form-section-title">

View file

@ -7,6 +7,7 @@ function ($scope, $state, Notifications, SettingsService, StateManager, DEFAULT_
customTemplates: false, customTemplates: false,
externalContributions: false, externalContributions: false,
restrictBindMounts: false, restrictBindMounts: false,
restrictPrivilegedMode: false,
labelName: '', labelName: '',
labelValue: '' labelValue: ''
}; };
@ -41,6 +42,7 @@ function ($scope, $state, Notifications, SettingsService, StateManager, DEFAULT_
} }
settings.DisplayExternalContributors = !$scope.formValues.externalContributions; settings.DisplayExternalContributors = !$scope.formValues.externalContributions;
settings.AllowBindMountsForRegularUsers = !$scope.formValues.restrictBindMounts; settings.AllowBindMountsForRegularUsers = !$scope.formValues.restrictBindMounts;
settings.AllowPrivilegedModeForRegularUsers = !$scope.formValues.restrictPrivilegedMode;
updateSettings(settings, false); updateSettings(settings, false);
}; };
@ -84,6 +86,7 @@ function ($scope, $state, Notifications, SettingsService, StateManager, DEFAULT_
} }
$scope.formValues.externalContributions = !settings.DisplayExternalContributors; $scope.formValues.externalContributions = !settings.DisplayExternalContributors;
$scope.formValues.restrictBindMounts = !settings.AllowBindMountsForRegularUsers; $scope.formValues.restrictBindMounts = !settings.AllowBindMountsForRegularUsers;
$scope.formValues.restrictPrivilegedMode = !settings.AllowPrivilegedModeForRegularUsers;
}) })
.catch(function error(err) { .catch(function error(err) {
Notifications.error('Failure', err, 'Unable to retrieve application settings'); Notifications.error('Failure', err, 'Unable to retrieve application settings');

View file

@ -6,4 +6,5 @@ function SettingsViewModel(data) {
this.AuthenticationMethod = data.AuthenticationMethod; this.AuthenticationMethod = data.AuthenticationMethod;
this.LDAPSettings = data.LDAPSettings; this.LDAPSettings = data.LDAPSettings;
this.AllowBindMountsForRegularUsers = data.AllowBindMountsForRegularUsers; this.AllowBindMountsForRegularUsers = data.AllowBindMountsForRegularUsers;
this.AllowPrivilegedModeForRegularUsers = data.AllowPrivilegedModeForRegularUsers;
} }