diff --git a/api/bolt/migrate_dbversion5.go b/api/bolt/migrate_dbversion5.go new file mode 100644 index 000000000..ef1bfd3ad --- /dev/null +++ b/api/bolt/migrate_dbversion5.go @@ -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 +} diff --git a/api/bolt/migrator.go b/api/bolt/migrator.go index 2730fe7e9..8a42cedc6 100644 --- a/api/bolt/migrator.go +++ b/api/bolt/migrator.go @@ -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 diff --git a/api/cmd/portainer/main.go b/api/cmd/portainer/main.go index ac8c7f57d..b7091cf7a 100644 --- a/api/cmd/portainer/main.go +++ b/api/cmd/portainer/main.go @@ -125,7 +125,8 @@ func initSettings(settingsService portainer.SettingsService, flags *portainer.CL portainer.LDAPSearchSettings{}, }, }, - AllowBindMountsForRegularUsers: true, + AllowBindMountsForRegularUsers: true, + AllowPrivilegedModeForRegularUsers: true, } if *flags.Templates != "" { diff --git a/api/http/handler/settings.go b/api/http/handler/settings.go index 8e3679e6f..5e47c92f5 100644 --- a/api/http/handler/settings.go +++ b/api/http/handler/settings.go @@ -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 { diff --git a/api/portainer.go b/api/portainer.go index bfbac90a9..fe8326848 100644 --- a/api/portainer.go +++ b/api/portainer.go @@ -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" ) diff --git a/app/components/createContainer/createContainerController.js b/app/components/createContainer/createContainerController.js index 77c44cff7..2906f81b5 100644 --- a/app/components/createContainer/createContainerController.js +++ b/app/components/createContainer/createContainerController.js @@ -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'); diff --git a/app/components/createContainer/createcontainer.html b/app/components/createContainer/createcontainer.html index fe61cd720..2701fe7d6 100644 --- a/app/components/createContainer/createcontainer.html +++ b/app/components/createContainer/createcontainer.html @@ -470,13 +470,13 @@
-
+
-
diff --git a/app/components/settings/settings.html b/app/components/settings/settings.html index d73f4eed6..7c5b5f0a0 100644 --- a/app/components/settings/settings.html +++ b/app/components/settings/settings.html @@ -26,6 +26,17 @@
+
+
+ + +
+
diff --git a/app/components/settings/settingsController.js b/app/components/settings/settingsController.js index c75f97084..cd038dd35 100644 --- a/app/components/settings/settingsController.js +++ b/app/components/settings/settingsController.js @@ -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'); diff --git a/app/models/api/settings/settings.js b/app/models/api/settings/settings.js index e0af9bcc2..4c130b052 100644 --- a/app/models/api/settings/settings.js +++ b/app/models/api/settings/settings.js @@ -6,4 +6,5 @@ function SettingsViewModel(data) { this.AuthenticationMethod = data.AuthenticationMethod; this.LDAPSettings = data.LDAPSettings; this.AllowBindMountsForRegularUsers = data.AllowBindMountsForRegularUsers; + this.AllowPrivilegedModeForRegularUsers = data.AllowPrivilegedModeForRegularUsers; }