1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-07-23 15:29:42 +02:00

feat(authentication): add a setting to toggle automatic user provisioning when u… (#2068)

* feat(api): add a setting to toggle automatic user provisioning when using LDAP authentication

* fix(auth): fix an issue with AutoCreateUsers disabled
This commit is contained in:
Anthony Lapenna 2018-07-24 08:49:17 +02:00 committed by GitHub
parent c7cb515035
commit 113da93145
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 44 additions and 18 deletions

View file

@ -8,6 +8,7 @@ func (m *Migrator) updateSettingsToVersion13() error {
return err return err
} }
legacySettings.LDAPSettings.AutoCreateUsers = false
legacySettings.LDAPSettings.GroupSearchSettings = []portainer.LDAPGroupSearchSettings{ legacySettings.LDAPSettings.GroupSearchSettings = []portainer.LDAPGroupSearchSettings{
portainer.LDAPGroupSearchSettings{}, portainer.LDAPGroupSearchSettings{},
} }

View file

@ -170,6 +170,7 @@ func (m *Migrator) Migrate() error {
} }
} }
// Portainer 1.18.2-dev
if m.currentDBVersion < 13 { if m.currentDBVersion < 13 {
err := m.updateSettingsToVersion13() err := m.updateSettingsToVersion13()
if err != nil { if err != nil {

View file

@ -164,7 +164,8 @@ func initSettings(settingsService portainer.SettingsService, flags *portainer.CL
LogoURL: *flags.Logo, LogoURL: *flags.Logo,
AuthenticationMethod: portainer.AuthenticationInternal, AuthenticationMethod: portainer.AuthenticationInternal,
LDAPSettings: portainer.LDAPSettings{ LDAPSettings: portainer.LDAPSettings{
TLSConfig: portainer.TLSConfiguration{}, AutoCreateUsers: true,
TLSConfig: portainer.TLSConfiguration{},
SearchSettings: []portainer.LDAPSearchSettings{ SearchSettings: []portainer.LDAPSearchSettings{
portainer.LDAPSearchSettings{}, portainer.LDAPSearchSettings{},
}, },

View file

@ -3,6 +3,7 @@ package auth
import ( import (
"log" "log"
"net/http" "net/http"
"strings"
"github.com/asaskevich/govalidator" "github.com/asaskevich/govalidator"
"github.com/portainer/portainer" "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 settings.AuthenticationMethod == portainer.AuthenticationLDAP {
if u == nil { if u == nil && settings.LDAPSettings.AutoCreateUsers {
return handler.authenticateLDAPAndCreateUser(w, payload.Username, payload.Password, &settings.LDAPSettings) 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) 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 { func teamExists(teamName string, ldapGroups []string) bool {
for _, group := range ldapGroups { for _, group := range ldapGroups {
if group == teamName { if strings.ToLower(group) == strings.ToLower(teamName) {
return true return true
} }
} }

View file

@ -13,7 +13,6 @@ type publicSettingsResponse struct {
AuthenticationMethod portainer.AuthenticationMethod `json:"AuthenticationMethod"` AuthenticationMethod portainer.AuthenticationMethod `json:"AuthenticationMethod"`
AllowBindMountsForRegularUsers bool `json:"AllowBindMountsForRegularUsers"` AllowBindMountsForRegularUsers bool `json:"AllowBindMountsForRegularUsers"`
AllowPrivilegedModeForRegularUsers bool `json:"AllowPrivilegedModeForRegularUsers"` AllowPrivilegedModeForRegularUsers bool `json:"AllowPrivilegedModeForRegularUsers"`
SnapshotInterval string `json:"SnapshotInterval"`
} }
// GET request on /api/settings/public // GET request on /api/settings/public
@ -28,7 +27,6 @@ func (handler *Handler) settingsPublic(w http.ResponseWriter, r *http.Request) *
AuthenticationMethod: settings.AuthenticationMethod, AuthenticationMethod: settings.AuthenticationMethod,
AllowBindMountsForRegularUsers: settings.AllowBindMountsForRegularUsers, AllowBindMountsForRegularUsers: settings.AllowBindMountsForRegularUsers,
AllowPrivilegedModeForRegularUsers: settings.AllowPrivilegedModeForRegularUsers, AllowPrivilegedModeForRegularUsers: settings.AllowPrivilegedModeForRegularUsers,
SnapshotInterval: settings.SnapshotInterval,
} }
return response.JSON(w, publicSettings) return response.JSON(w, publicSettings)

View file

@ -53,6 +53,7 @@ type (
StartTLS bool `json:"StartTLS"` StartTLS bool `json:"StartTLS"`
SearchSettings []LDAPSearchSettings `json:"SearchSettings"` SearchSettings []LDAPSearchSettings `json:"SearchSettings"`
GroupSearchSettings []LDAPGroupSearchSettings `json:"GroupSearchSettings"` GroupSearchSettings []LDAPGroupSearchSettings `json:"GroupSearchSettings"`
AutoCreateUsers bool `json:"AutoCreateUsers"`
} }
// TLSConfiguration represents a TLS configuration. // TLSConfiguration represents a TLS configuration.

View file

@ -2942,6 +2942,10 @@ definitions:
type: "array" type: "array"
items: items:
$ref: "#/definitions/LDAPGroupSearchSettings" $ref: "#/definitions/LDAPGroupSearchSettings"
AutoCreateUsers:
type: "boolean"
example: "true"
description: "Automatically provision users and assign them to matching LDAP group names"
Settings: Settings:
type: "object" type: "object"

View file

@ -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) { function LDAPSettingsViewModel(data) {
this.ReaderDN = data.ReaderDN; this.ReaderDN = data.ReaderDN;
this.Password = data.Password; this.Password = data.Password;
this.URL = data.URL; this.URL = data.URL;
this.SearchSettings = data.SearchSettings; this.SearchSettings = data.SearchSettings;
this.GroupSearchSettings = data.GroupSearchSettings; this.GroupSearchSettings = data.GroupSearchSettings;
this.AutoCreateUsers = data.AutoCreateUsers;
} }
function LDAPSearchSettings(BaseDN, UsernameAttribute, Filter) { function LDAPSearchSettings(BaseDN, UsernameAttribute, Filter) {

View file

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

View file

@ -50,10 +50,6 @@
<div class="form-group" ng-if="settings.AuthenticationMethod === 2"> <div class="form-group" ng-if="settings.AuthenticationMethod === 2">
<span class="col-sm-12 text-muted small"> <span class="col-sm-12 text-muted small">
When using LDAP authentication, Portainer will delegate user authentication to a LDAP server and fallback to internal authentication if LDAP authentication fails. When using LDAP authentication, Portainer will delegate user authentication to a LDAP server and fallback to internal authentication if LDAP authentication fails.
<p style="margin-top:5px;">
<i class="fa fa-exclamation-triangle orange-icon" aria-hidden="true" style="margin-right: 2px;"></i>
<u>Portainer will create user(s) automatically with standard user role and assign them to team(s) which matches to LDAP group name(s).</u>
</p>
</span> </span>
</div> </div>
@ -182,6 +178,25 @@
</div> </div>
</div> </div>
<div class="col-sm-12 form-section-title">
Automatic user provisioning
</div>
<div class="form-group">
<span class="col-sm-12 text-muted small">
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.
</span>
</div>
<div class="form-group">
<div class="col-sm-12">
<label for="tls" class="control-label text-left">
Automatic user provisioning
</label>
<label class="switch" style="margin-left: 20px;">
<input type="checkbox" ng-model="LDAPSettings.AutoCreateUsers"><i></i>
</label>
</div>
</div>
<div class="col-sm-12 form-section-title"> <div class="col-sm-12 form-section-title">
User search configurations User search configurations
</div> </div>