From 113da93145995444e9641ead72c1c2bb9a10fd39 Mon Sep 17 00:00:00 2001 From: Anthony Lapenna Date: Tue, 24 Jul 2018 08:49:17 +0200 Subject: [PATCH] =?UTF-8?q?feat(authentication):=20add=20a=20setting=20to?= =?UTF-8?q?=20toggle=20automatic=20user=20provisioning=20when=20u=E2=80=A6?= =?UTF-8?q?=20(#2068)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(api): add a setting to toggle automatic user provisioning when using LDAP authentication * fix(auth): fix an issue with AutoCreateUsers disabled --- api/bolt/migrator/migrate_dbversion12.go | 1 + api/bolt/migrator/migrator.go | 1 + api/cmd/portainer/main.go | 3 ++- api/http/handler/auth/authenticate.go | 7 ++++-- api/http/handler/settings/settings_public.go | 2 -- api/portainer.go | 1 + api/swagger.yaml | 4 ++++ .../{settings/ldapSettings.js => settings.js} | 11 +++++++++ app/portainer/models/settings/settings.js | 9 -------- .../settingsAuthentication.html | 23 +++++++++++++++---- 10 files changed, 44 insertions(+), 18 deletions(-) rename app/portainer/models/{settings/ldapSettings.js => settings.js} (54%) delete mode 100644 app/portainer/models/settings/settings.js diff --git a/api/bolt/migrator/migrate_dbversion12.go b/api/bolt/migrator/migrate_dbversion12.go index 465c10682..0d2bf0554 100644 --- a/api/bolt/migrator/migrate_dbversion12.go +++ b/api/bolt/migrator/migrate_dbversion12.go @@ -8,6 +8,7 @@ func (m *Migrator) updateSettingsToVersion13() error { return err } + legacySettings.LDAPSettings.AutoCreateUsers = false legacySettings.LDAPSettings.GroupSearchSettings = []portainer.LDAPGroupSearchSettings{ portainer.LDAPGroupSearchSettings{}, } diff --git a/api/bolt/migrator/migrator.go b/api/bolt/migrator/migrator.go index efae952d8..5b03aa806 100644 --- a/api/bolt/migrator/migrator.go +++ b/api/bolt/migrator/migrator.go @@ -170,6 +170,7 @@ func (m *Migrator) Migrate() error { } } + // Portainer 1.18.2-dev if m.currentDBVersion < 13 { err := m.updateSettingsToVersion13() if err != nil { diff --git a/api/cmd/portainer/main.go b/api/cmd/portainer/main.go index 01a73d41f..567ff4c9e 100644 --- a/api/cmd/portainer/main.go +++ b/api/cmd/portainer/main.go @@ -164,7 +164,8 @@ func initSettings(settingsService portainer.SettingsService, flags *portainer.CL LogoURL: *flags.Logo, AuthenticationMethod: portainer.AuthenticationInternal, LDAPSettings: portainer.LDAPSettings{ - TLSConfig: portainer.TLSConfiguration{}, + AutoCreateUsers: true, + TLSConfig: portainer.TLSConfiguration{}, SearchSettings: []portainer.LDAPSearchSettings{ portainer.LDAPSearchSettings{}, }, diff --git a/api/http/handler/auth/authenticate.go b/api/http/handler/auth/authenticate.go index e473e60fc..cf928357b 100644 --- a/api/http/handler/auth/authenticate.go +++ b/api/http/handler/auth/authenticate.go @@ -3,6 +3,7 @@ package auth import ( "log" "net/http" + "strings" "github.com/asaskevich/govalidator" "github.com/portainer/portainer" @@ -56,8 +57,10 @@ func (handler *Handler) authenticate(w http.ResponseWriter, r *http.Request) *ht } if settings.AuthenticationMethod == portainer.AuthenticationLDAP { - if u == nil { + if u == nil && settings.LDAPSettings.AutoCreateUsers { return handler.authenticateLDAPAndCreateUser(w, payload.Username, payload.Password, &settings.LDAPSettings) + } else if u == nil && !settings.LDAPSettings.AutoCreateUsers { + return &httperror.HandlerError{http.StatusUnprocessableEntity, "Invalid credentials", portainer.ErrUnauthorized} } return handler.authenticateLDAP(w, u, payload.Password, &settings.LDAPSettings) } @@ -167,7 +170,7 @@ func (handler *Handler) addUserIntoTeams(user *portainer.User, settings *portain func teamExists(teamName string, ldapGroups []string) bool { for _, group := range ldapGroups { - if group == teamName { + if strings.ToLower(group) == strings.ToLower(teamName) { return true } } diff --git a/api/http/handler/settings/settings_public.go b/api/http/handler/settings/settings_public.go index 690688079..c2ee2a616 100644 --- a/api/http/handler/settings/settings_public.go +++ b/api/http/handler/settings/settings_public.go @@ -13,7 +13,6 @@ type publicSettingsResponse struct { AuthenticationMethod portainer.AuthenticationMethod `json:"AuthenticationMethod"` AllowBindMountsForRegularUsers bool `json:"AllowBindMountsForRegularUsers"` AllowPrivilegedModeForRegularUsers bool `json:"AllowPrivilegedModeForRegularUsers"` - SnapshotInterval string `json:"SnapshotInterval"` } // GET request on /api/settings/public @@ -28,7 +27,6 @@ func (handler *Handler) settingsPublic(w http.ResponseWriter, r *http.Request) * AuthenticationMethod: settings.AuthenticationMethod, AllowBindMountsForRegularUsers: settings.AllowBindMountsForRegularUsers, AllowPrivilegedModeForRegularUsers: settings.AllowPrivilegedModeForRegularUsers, - SnapshotInterval: settings.SnapshotInterval, } return response.JSON(w, publicSettings) diff --git a/api/portainer.go b/api/portainer.go index 610e0bdac..d2a75e345 100644 --- a/api/portainer.go +++ b/api/portainer.go @@ -53,6 +53,7 @@ type ( StartTLS bool `json:"StartTLS"` SearchSettings []LDAPSearchSettings `json:"SearchSettings"` GroupSearchSettings []LDAPGroupSearchSettings `json:"GroupSearchSettings"` + AutoCreateUsers bool `json:"AutoCreateUsers"` } // TLSConfiguration represents a TLS configuration. diff --git a/api/swagger.yaml b/api/swagger.yaml index fefd61d33..7b556b0eb 100644 --- a/api/swagger.yaml +++ b/api/swagger.yaml @@ -2942,6 +2942,10 @@ definitions: type: "array" items: $ref: "#/definitions/LDAPGroupSearchSettings" + AutoCreateUsers: + type: "boolean" + example: "true" + description: "Automatically provision users and assign them to matching LDAP group names" Settings: type: "object" diff --git a/app/portainer/models/settings/ldapSettings.js b/app/portainer/models/settings.js similarity index 54% rename from app/portainer/models/settings/ldapSettings.js rename to app/portainer/models/settings.js index 3bd02225c..16ec568c2 100644 --- a/app/portainer/models/settings/ldapSettings.js +++ b/app/portainer/models/settings.js @@ -1,9 +1,20 @@ +function SettingsViewModel(data) { + this.LogoURL = data.LogoURL; + this.BlackListedLabels = data.BlackListedLabels; + this.AuthenticationMethod = data.AuthenticationMethod; + this.LDAPSettings = data.LDAPSettings; + this.AllowBindMountsForRegularUsers = data.AllowBindMountsForRegularUsers; + this.AllowPrivilegedModeForRegularUsers = data.AllowPrivilegedModeForRegularUsers; + this.SnapshotInterval = data.SnapshotInterval; +} + function LDAPSettingsViewModel(data) { this.ReaderDN = data.ReaderDN; this.Password = data.Password; this.URL = data.URL; this.SearchSettings = data.SearchSettings; this.GroupSearchSettings = data.GroupSearchSettings; + this.AutoCreateUsers = data.AutoCreateUsers; } function LDAPSearchSettings(BaseDN, UsernameAttribute, Filter) { diff --git a/app/portainer/models/settings/settings.js b/app/portainer/models/settings/settings.js deleted file mode 100644 index a791a4ca2..000000000 --- a/app/portainer/models/settings/settings.js +++ /dev/null @@ -1,9 +0,0 @@ -function SettingsViewModel(data) { - this.LogoURL = data.LogoURL; - this.BlackListedLabels = data.BlackListedLabels; - this.AuthenticationMethod = data.AuthenticationMethod; - this.LDAPSettings = data.LDAPSettings; - this.AllowBindMountsForRegularUsers = data.AllowBindMountsForRegularUsers; - this.AllowPrivilegedModeForRegularUsers = data.AllowPrivilegedModeForRegularUsers; - this.SnapshotInterval = data.SnapshotInterval; -} diff --git a/app/portainer/views/settings/authentication/settingsAuthentication.html b/app/portainer/views/settings/authentication/settingsAuthentication.html index fad5137d3..72db0edef 100644 --- a/app/portainer/views/settings/authentication/settingsAuthentication.html +++ b/app/portainer/views/settings/authentication/settingsAuthentication.html @@ -50,10 +50,6 @@
When using LDAP authentication, Portainer will delegate user authentication to a LDAP server and fallback to internal authentication if LDAP authentication fails. -

- - Portainer will create user(s) automatically with standard user role and assign them to team(s) which matches to LDAP group name(s). -

@@ -182,6 +178,25 @@ +
+ Automatic user provisioning +
+
+ + With automatic user provisioning enabled, Portainer will create user(s) automatically with standard user role and assign them to team(s) which matches to LDAP group name(s). If disabled, users must be created in Portainer beforehand. + +
+
+
+ + +
+
+
User search configurations