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
pull/2071/head
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
}
legacySettings.LDAPSettings.AutoCreateUsers = false
legacySettings.LDAPSettings.GroupSearchSettings = []portainer.LDAPGroupSearchSettings{
portainer.LDAPGroupSearchSettings{},
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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) {
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) {

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">
<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.
<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>
</div>
@ -182,6 +178,25 @@
</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">
User search configurations
</div>