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:
parent
c7cb515035
commit
113da93145
10 changed files with 44 additions and 18 deletions
|
@ -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{},
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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{},
|
||||||
},
|
},
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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) {
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue