From cd58c16b4e16e08eeecd06c5993f9d797768b0f4 Mon Sep 17 00:00:00 2001 From: Chaim Lev-Ari Date: Mon, 13 Jul 2020 09:36:47 +0300 Subject: [PATCH] feat(settings): hide stacks for non admin when settings is set (#4025) * refactor(settings): replace disableDeviceMapping with allow * feat(dashboard): hide stacks if settings disabled and non admin * refactor(sidebar): check if user is endpoint admin * feat(settings): set the default value for stack management * feat(settings): rename field label * fix(sidebar): refresh show stacks state --- api/bolt/migrator/migrate_dbversion22.go | 1 + api/cmd/portainer/main.go | 19 ++++---- api/http/handler/settings/settings_public.go | 46 +++++++++---------- api/http/handler/settings/settings_update.go | 36 +++++++-------- api/http/handler/stacks/stack_create.go | 2 +- api/portainer.go | 32 ++++++------- .../docker-sidebar-content.js | 2 +- .../dockerSidebarContent.html | 2 +- app/docker/views/dashboard/dashboard.html | 2 +- .../views/dashboard/dashboardController.js | 22 ++++++++- app/portainer/models/settings.js | 4 +- app/portainer/services/stateManager.js | 6 +-- .../views/settings/settingsController.js | 8 ++-- app/portainer/views/sidebar/sidebar.html | 2 +- .../views/sidebar/sidebarController.js | 26 ++++++++++- .../views/stacks/stacksController.js | 2 +- 16 files changed, 128 insertions(+), 84 deletions(-) diff --git a/api/bolt/migrator/migrate_dbversion22.go b/api/bolt/migrator/migrate_dbversion22.go index 25ee3fc7f..9d996bf6f 100644 --- a/api/bolt/migrator/migrate_dbversion22.go +++ b/api/bolt/migrator/migrate_dbversion22.go @@ -11,6 +11,7 @@ func (m *Migrator) updateSettingsToDBVersion23() error { } legacySettings.AllowDeviceMappingForRegularUsers = true + legacySettings.AllowStackManagementForRegularUsers = true return m.settingsService.UpdateSettings(legacySettings) } diff --git a/api/cmd/portainer/main.go b/api/cmd/portainer/main.go index aa7a5bbc3..e5a4589c7 100644 --- a/api/cmd/portainer/main.go +++ b/api/cmd/portainer/main.go @@ -269,15 +269,16 @@ func initSettings(settingsService portainer.SettingsService, flags *portainer.CL portainer.LDAPGroupSearchSettings{}, }, }, - OAuthSettings: portainer.OAuthSettings{}, - AllowBindMountsForRegularUsers: true, - AllowPrivilegedModeForRegularUsers: true, - AllowVolumeBrowserForRegularUsers: false, - AllowDeviceMappingForRegularUsers: true, - EnableHostManagementFeatures: false, - AllowHostNamespaceForRegularUsers: true, - SnapshotInterval: *flags.SnapshotInterval, - EdgeAgentCheckinInterval: portainer.DefaultEdgeAgentCheckinIntervalInSeconds, + OAuthSettings: portainer.OAuthSettings{}, + AllowBindMountsForRegularUsers: true, + AllowPrivilegedModeForRegularUsers: true, + AllowVolumeBrowserForRegularUsers: false, + AllowDeviceMappingForRegularUsers: true, + AllowStackManagementForRegularUsers: true, + EnableHostManagementFeatures: false, + AllowHostNamespaceForRegularUsers: true, + SnapshotInterval: *flags.SnapshotInterval, + EdgeAgentCheckinInterval: portainer.DefaultEdgeAgentCheckinIntervalInSeconds, } if *flags.Templates != "" { diff --git a/api/http/handler/settings/settings_public.go b/api/http/handler/settings/settings_public.go index b57ad8682..7d23319dc 100644 --- a/api/http/handler/settings/settings_public.go +++ b/api/http/handler/settings/settings_public.go @@ -10,18 +10,18 @@ import ( ) type publicSettingsResponse struct { - LogoURL string `json:"LogoURL"` - AuthenticationMethod portainer.AuthenticationMethod `json:"AuthenticationMethod"` - AllowBindMountsForRegularUsers bool `json:"AllowBindMountsForRegularUsers"` - AllowPrivilegedModeForRegularUsers bool `json:"AllowPrivilegedModeForRegularUsers"` - AllowVolumeBrowserForRegularUsers bool `json:"AllowVolumeBrowserForRegularUsers"` - EnableHostManagementFeatures bool `json:"EnableHostManagementFeatures"` - EnableEdgeComputeFeatures bool `json:"EnableEdgeComputeFeatures"` - ExternalTemplates bool `json:"ExternalTemplates"` - OAuthLoginURI string `json:"OAuthLoginURI"` - DisableStackManagementForRegularUsers bool `json:"DisableStackManagementForRegularUsers"` - AllowHostNamespaceForRegularUsers bool `json:"AllowHostNamespaceForRegularUsers"` - AllowDeviceMappingForRegularUsers bool `json:"AllowDeviceMappingForRegularUsers"` + LogoURL string `json:"LogoURL"` + AuthenticationMethod portainer.AuthenticationMethod `json:"AuthenticationMethod"` + AllowBindMountsForRegularUsers bool `json:"AllowBindMountsForRegularUsers"` + AllowPrivilegedModeForRegularUsers bool `json:"AllowPrivilegedModeForRegularUsers"` + AllowVolumeBrowserForRegularUsers bool `json:"AllowVolumeBrowserForRegularUsers"` + EnableHostManagementFeatures bool `json:"EnableHostManagementFeatures"` + EnableEdgeComputeFeatures bool `json:"EnableEdgeComputeFeatures"` + ExternalTemplates bool `json:"ExternalTemplates"` + OAuthLoginURI string `json:"OAuthLoginURI"` + AllowStackManagementForRegularUsers bool `json:"AllowStackManagementForRegularUsers"` + AllowHostNamespaceForRegularUsers bool `json:"AllowHostNamespaceForRegularUsers"` + AllowDeviceMappingForRegularUsers bool `json:"AllowDeviceMappingForRegularUsers"` } // GET request on /api/settings/public @@ -32,22 +32,22 @@ func (handler *Handler) settingsPublic(w http.ResponseWriter, r *http.Request) * } publicSettings := &publicSettingsResponse{ - LogoURL: settings.LogoURL, - AuthenticationMethod: settings.AuthenticationMethod, - AllowBindMountsForRegularUsers: settings.AllowBindMountsForRegularUsers, - AllowPrivilegedModeForRegularUsers: settings.AllowPrivilegedModeForRegularUsers, - AllowVolumeBrowserForRegularUsers: settings.AllowVolumeBrowserForRegularUsers, - EnableHostManagementFeatures: settings.EnableHostManagementFeatures, - EnableEdgeComputeFeatures: settings.EnableEdgeComputeFeatures, - AllowHostNamespaceForRegularUsers: settings.AllowHostNamespaceForRegularUsers, - ExternalTemplates: false, + LogoURL: settings.LogoURL, + AuthenticationMethod: settings.AuthenticationMethod, + AllowBindMountsForRegularUsers: settings.AllowBindMountsForRegularUsers, + AllowPrivilegedModeForRegularUsers: settings.AllowPrivilegedModeForRegularUsers, + AllowVolumeBrowserForRegularUsers: settings.AllowVolumeBrowserForRegularUsers, + EnableHostManagementFeatures: settings.EnableHostManagementFeatures, + EnableEdgeComputeFeatures: settings.EnableEdgeComputeFeatures, + AllowHostNamespaceForRegularUsers: settings.AllowHostNamespaceForRegularUsers, + AllowStackManagementForRegularUsers: settings.AllowStackManagementForRegularUsers, + ExternalTemplates: false, OAuthLoginURI: fmt.Sprintf("%s?response_type=code&client_id=%s&redirect_uri=%s&scope=%s&prompt=login", settings.OAuthSettings.AuthorizationURI, settings.OAuthSettings.ClientID, settings.OAuthSettings.RedirectURI, settings.OAuthSettings.Scopes), - AllowDeviceMappingForRegularUsers: settings.AllowDeviceMappingForRegularUsers, - DisableStackManagementForRegularUsers: settings.DisableStackManagementForRegularUsers, + AllowDeviceMappingForRegularUsers: settings.AllowDeviceMappingForRegularUsers, } if settings.TemplatesURL != "" { diff --git a/api/http/handler/settings/settings_update.go b/api/http/handler/settings/settings_update.go index 7611fb7f6..308253b1e 100644 --- a/api/http/handler/settings/settings_update.go +++ b/api/http/handler/settings/settings_update.go @@ -12,22 +12,22 @@ import ( ) type settingsUpdatePayload struct { - LogoURL *string - BlackListedLabels []portainer.Pair - AuthenticationMethod *int - LDAPSettings *portainer.LDAPSettings - OAuthSettings *portainer.OAuthSettings - AllowBindMountsForRegularUsers *bool - AllowPrivilegedModeForRegularUsers *bool - AllowVolumeBrowserForRegularUsers *bool - EnableHostManagementFeatures *bool - SnapshotInterval *string - TemplatesURL *string - EdgeAgentCheckinInterval *int - EnableEdgeComputeFeatures *bool - DisableStackManagementForRegularUsers *bool - AllowHostNamespaceForRegularUsers *bool - AllowDeviceMappingForRegularUsers *bool + LogoURL *string + BlackListedLabels []portainer.Pair + AuthenticationMethod *int + LDAPSettings *portainer.LDAPSettings + OAuthSettings *portainer.OAuthSettings + AllowBindMountsForRegularUsers *bool + AllowPrivilegedModeForRegularUsers *bool + AllowVolumeBrowserForRegularUsers *bool + EnableHostManagementFeatures *bool + SnapshotInterval *string + TemplatesURL *string + EdgeAgentCheckinInterval *int + EnableEdgeComputeFeatures *bool + AllowStackManagementForRegularUsers *bool + AllowHostNamespaceForRegularUsers *bool + AllowDeviceMappingForRegularUsers *bool } func (payload *settingsUpdatePayload) Validate(r *http.Request) error { @@ -117,8 +117,8 @@ func (handler *Handler) settingsUpdate(w http.ResponseWriter, r *http.Request) * settings.EnableEdgeComputeFeatures = *payload.EnableEdgeComputeFeatures } - if payload.DisableStackManagementForRegularUsers != nil { - settings.DisableStackManagementForRegularUsers = *payload.DisableStackManagementForRegularUsers + if payload.AllowStackManagementForRegularUsers != nil { + settings.AllowStackManagementForRegularUsers = *payload.AllowStackManagementForRegularUsers } if payload.AllowHostNamespaceForRegularUsers != nil { diff --git a/api/http/handler/stacks/stack_create.go b/api/http/handler/stacks/stack_create.go index e89708d5d..4ac2b3638 100644 --- a/api/http/handler/stacks/stack_create.go +++ b/api/http/handler/stacks/stack_create.go @@ -48,7 +48,7 @@ func (handler *Handler) stackCreate(w http.ResponseWriter, r *http.Request) *htt return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve settings from the database", err} } - if settings.DisableStackManagementForRegularUsers { + if !settings.AllowStackManagementForRegularUsers { securityContext, err := security.RetrieveRestrictedRequestContext(r) if err != nil { return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve user info from request context", err} diff --git a/api/portainer.go b/api/portainer.go index 882a69344..917387600 100644 --- a/api/portainer.go +++ b/api/portainer.go @@ -420,22 +420,22 @@ type ( // Settings represents the application settings Settings struct { - LogoURL string `json:"LogoURL"` - BlackListedLabels []Pair `json:"BlackListedLabels"` - AuthenticationMethod AuthenticationMethod `json:"AuthenticationMethod"` - LDAPSettings LDAPSettings `json:"LDAPSettings"` - OAuthSettings OAuthSettings `json:"OAuthSettings"` - AllowBindMountsForRegularUsers bool `json:"AllowBindMountsForRegularUsers"` - AllowPrivilegedModeForRegularUsers bool `json:"AllowPrivilegedModeForRegularUsers"` - AllowVolumeBrowserForRegularUsers bool `json:"AllowVolumeBrowserForRegularUsers"` - SnapshotInterval string `json:"SnapshotInterval"` - TemplatesURL string `json:"TemplatesURL"` - EnableHostManagementFeatures bool `json:"EnableHostManagementFeatures"` - EdgeAgentCheckinInterval int `json:"EdgeAgentCheckinInterval"` - EnableEdgeComputeFeatures bool `json:"EnableEdgeComputeFeatures"` - DisableStackManagementForRegularUsers bool `json:"DisableStackManagementForRegularUsers"` - AllowHostNamespaceForRegularUsers bool `json:"AllowHostNamespaceForRegularUsers"` - AllowDeviceMappingForRegularUsers bool `json:"AllowDeviceMappingForRegularUsers"` + LogoURL string `json:"LogoURL"` + BlackListedLabels []Pair `json:"BlackListedLabels"` + AuthenticationMethod AuthenticationMethod `json:"AuthenticationMethod"` + LDAPSettings LDAPSettings `json:"LDAPSettings"` + OAuthSettings OAuthSettings `json:"OAuthSettings"` + AllowBindMountsForRegularUsers bool `json:"AllowBindMountsForRegularUsers"` + AllowPrivilegedModeForRegularUsers bool `json:"AllowPrivilegedModeForRegularUsers"` + AllowVolumeBrowserForRegularUsers bool `json:"AllowVolumeBrowserForRegularUsers"` + SnapshotInterval string `json:"SnapshotInterval"` + TemplatesURL string `json:"TemplatesURL"` + EnableHostManagementFeatures bool `json:"EnableHostManagementFeatures"` + EdgeAgentCheckinInterval int `json:"EdgeAgentCheckinInterval"` + EnableEdgeComputeFeatures bool `json:"EnableEdgeComputeFeatures"` + AllowStackManagementForRegularUsers bool `json:"AllowStackManagementForRegularUsers"` + AllowHostNamespaceForRegularUsers bool `json:"AllowHostNamespaceForRegularUsers"` + AllowDeviceMappingForRegularUsers bool `json:"AllowDeviceMappingForRegularUsers"` // Deprecated fields DisplayDonationHeader bool diff --git a/app/docker/components/dockerSidebarContent/docker-sidebar-content.js b/app/docker/components/dockerSidebarContent/docker-sidebar-content.js index 5c3eaac3f..26cc72201 100644 --- a/app/docker/components/dockerSidebarContent/docker-sidebar-content.js +++ b/app/docker/components/dockerSidebarContent/docker-sidebar-content.js @@ -6,6 +6,6 @@ angular.module('portainer.docker').component('dockerSidebarContent', { standaloneManagement: '<', adminAccess: '<', offlineMode: '<', - hideStacks: '<', + showStacks: '<', }, }); diff --git a/app/docker/components/dockerSidebarContent/dockerSidebarContent.html b/app/docker/components/dockerSidebarContent/dockerSidebarContent.html index 2b7915c6a..3dc8249b9 100644 --- a/app/docker/components/dockerSidebarContent/dockerSidebarContent.html +++ b/app/docker/components/dockerSidebarContent/dockerSidebarContent.html @@ -4,7 +4,7 @@ -