feat(authentiation): check ldap support for extended operations on startup (#2133)
* feat(authentiation): check ldap server on startup This PR adds a startup check to the LDAP authentication backend. It additionally adds support for checking supportedExtension OIDs, currently only checking passwdModifyOID (1.3.6.1.4.1.4203.1.11.3). This can relatively easily be enhanced to add detection for other rootDSE capabilities like supportedControl and supportedCapabilities as necessary. * test(authentication): add unit tests for new feature * refactor(authentication): factorize ldap user provider newup * refactor: minor adjustmentspull/2139/head
parent
f759b27bb0
commit
cb71df5d9b
|
@ -94,13 +94,19 @@ func startServer() {
|
||||||
logger.Fatalf("Unrecognized storage backend")
|
logger.Fatalf("Unrecognized storage backend")
|
||||||
}
|
}
|
||||||
|
|
||||||
var userProvider authentication.UserProvider
|
var (
|
||||||
|
userProvider authentication.UserProvider
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case config.AuthenticationBackend.File != nil:
|
case config.AuthenticationBackend.File != nil:
|
||||||
userProvider = authentication.NewFileUserProvider(config.AuthenticationBackend.File)
|
userProvider = authentication.NewFileUserProvider(config.AuthenticationBackend.File)
|
||||||
case config.AuthenticationBackend.LDAP != nil:
|
case config.AuthenticationBackend.LDAP != nil:
|
||||||
userProvider = authentication.NewLDAPUserProvider(*config.AuthenticationBackend.LDAP, autheliaCertPool)
|
userProvider, err = authentication.NewLDAPUserProvider(*config.AuthenticationBackend.LDAP, autheliaCertPool)
|
||||||
|
if err != nil {
|
||||||
|
logger.Fatalf("Failed to Check LDAP Authentication Backend: %v", err)
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
logger.Fatalf("Unrecognized authentication backend")
|
logger.Fatalf("Unrecognized authentication backend")
|
||||||
}
|
}
|
||||||
|
@ -117,7 +123,7 @@ func startServer() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !config.Notifier.DisableStartupCheck {
|
if !config.Notifier.DisableStartupCheck {
|
||||||
_, err := notifier.StartupCheck()
|
_, err = notifier.StartupCheck()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Fatalf("Error during notifier startup check: %s", err)
|
logger.Fatalf("Error during notifier startup check: %s", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,11 @@ const (
|
||||||
Push = "mobile_push"
|
Push = "mobile_push"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
ldapSupportedExtensionAttribute = "supportedExtension"
|
||||||
|
ldapOIDPasswdModifyExtension = "1.3.6.1.4.1.4203.1.11.3"
|
||||||
|
)
|
||||||
|
|
||||||
// PossibleMethods is the set of all possible 2FA methods.
|
// PossibleMethods is the set of all possible 2FA methods.
|
||||||
var PossibleMethods = []string{TOTP, U2F, Push}
|
var PossibleMethods = []string{TOTP, U2F, Push}
|
||||||
|
|
||||||
|
|
|
@ -24,10 +24,29 @@ type LDAPUserProvider struct {
|
||||||
connectionFactory LDAPConnectionFactory
|
connectionFactory LDAPConnectionFactory
|
||||||
usersBaseDN string
|
usersBaseDN string
|
||||||
groupsBaseDN string
|
groupsBaseDN string
|
||||||
|
|
||||||
|
supportExtensionPasswdModify bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewLDAPUserProvider creates a new instance of LDAPUserProvider.
|
// NewLDAPUserProvider creates a new instance of LDAPUserProvider.
|
||||||
func NewLDAPUserProvider(configuration schema.LDAPAuthenticationBackendConfiguration, certPool *x509.CertPool) *LDAPUserProvider {
|
func NewLDAPUserProvider(configuration schema.LDAPAuthenticationBackendConfiguration, certPool *x509.CertPool) (provider *LDAPUserProvider, err error) {
|
||||||
|
provider = newLDAPUserProvider(configuration, certPool, nil)
|
||||||
|
|
||||||
|
err = provider.checkServer()
|
||||||
|
if err != nil {
|
||||||
|
return provider, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if provider.supportExtensionPasswdModify {
|
||||||
|
provider.logger.Trace("LDAP Server does support passwdModifyOID Extension")
|
||||||
|
} else {
|
||||||
|
provider.logger.Trace("LDAP Server does not support passwdModifyOID Extension")
|
||||||
|
}
|
||||||
|
|
||||||
|
return provider, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func newLDAPUserProvider(configuration schema.LDAPAuthenticationBackendConfiguration, certPool *x509.CertPool, factory LDAPConnectionFactory) (provider *LDAPUserProvider) {
|
||||||
if configuration.TLS == nil {
|
if configuration.TLS == nil {
|
||||||
configuration.TLS = schema.DefaultLDAPAuthenticationBackendConfiguration.TLS
|
configuration.TLS = schema.DefaultLDAPAuthenticationBackendConfiguration.TLS
|
||||||
}
|
}
|
||||||
|
@ -40,12 +59,16 @@ func NewLDAPUserProvider(configuration schema.LDAPAuthenticationBackendConfigura
|
||||||
dialOpts = ldap.DialWithTLSConfig(tlsConfig)
|
dialOpts = ldap.DialWithTLSConfig(tlsConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
provider := &LDAPUserProvider{
|
if factory == nil {
|
||||||
|
factory = NewLDAPConnectionFactoryImpl()
|
||||||
|
}
|
||||||
|
|
||||||
|
provider = &LDAPUserProvider{
|
||||||
configuration: configuration,
|
configuration: configuration,
|
||||||
tlsConfig: tlsConfig,
|
tlsConfig: tlsConfig,
|
||||||
dialOpts: dialOpts,
|
dialOpts: dialOpts,
|
||||||
logger: logging.Logger(),
|
logger: logging.Logger(),
|
||||||
connectionFactory: NewLDAPConnectionFactoryImpl(),
|
connectionFactory: factory,
|
||||||
}
|
}
|
||||||
|
|
||||||
provider.parseDynamicConfiguration()
|
provider.parseDynamicConfiguration()
|
||||||
|
@ -53,14 +76,6 @@ func NewLDAPUserProvider(configuration schema.LDAPAuthenticationBackendConfigura
|
||||||
return provider
|
return provider
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewLDAPUserProviderWithFactory creates a new instance of LDAPUserProvider with existing factory.
|
|
||||||
func NewLDAPUserProviderWithFactory(configuration schema.LDAPAuthenticationBackendConfiguration, certPool *x509.CertPool, connectionFactory LDAPConnectionFactory) *LDAPUserProvider {
|
|
||||||
provider := NewLDAPUserProvider(configuration, certPool)
|
|
||||||
provider.connectionFactory = connectionFactory
|
|
||||||
|
|
||||||
return provider
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *LDAPUserProvider) parseDynamicConfiguration() {
|
func (p *LDAPUserProvider) parseDynamicConfiguration() {
|
||||||
p.configuration.UsersFilter = strings.ReplaceAll(p.configuration.UsersFilter, "{username_attribute}", p.configuration.UsernameAttribute)
|
p.configuration.UsersFilter = strings.ReplaceAll(p.configuration.UsersFilter, "{username_attribute}", p.configuration.UsernameAttribute)
|
||||||
p.configuration.UsersFilter = strings.ReplaceAll(p.configuration.UsersFilter, "{mail_attribute}", p.configuration.MailAttribute)
|
p.configuration.UsersFilter = strings.ReplaceAll(p.configuration.UsersFilter, "{mail_attribute}", p.configuration.MailAttribute)
|
||||||
|
@ -85,6 +100,43 @@ func (p *LDAPUserProvider) parseDynamicConfiguration() {
|
||||||
p.logger.Tracef("Dynamically generated groups BaseDN is %s", p.groupsBaseDN)
|
p.logger.Tracef("Dynamically generated groups BaseDN is %s", p.groupsBaseDN)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *LDAPUserProvider) checkServer() (err error) {
|
||||||
|
conn, err := p.connect(p.configuration.User, p.configuration.Password)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
searchRequest := ldap.NewSearchRequest("", ldap.ScopeBaseObject, ldap.NeverDerefAliases,
|
||||||
|
1, 0, false, "(objectClass=*)", []string{ldapSupportedExtensionAttribute}, nil)
|
||||||
|
|
||||||
|
sr, err := conn.Search(searchRequest)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(sr.Entries) != 1 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterate the attribute values to see what the server supports.
|
||||||
|
for _, attr := range sr.Entries[0].Attributes {
|
||||||
|
if attr.Name == ldapSupportedExtensionAttribute {
|
||||||
|
p.logger.Tracef("LDAP Supported Extension OIDs: %s", strings.Join(attr.Values, ", "))
|
||||||
|
|
||||||
|
for _, oid := range attr.Values {
|
||||||
|
if oid == ldapOIDPasswdModifyExtension {
|
||||||
|
p.supportExtensionPasswdModify = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (p *LDAPUserProvider) connect(userDN string, password string) (LDAPConnection, error) {
|
func (p *LDAPUserProvider) connect(userDN string, password string) (LDAPConnection, error) {
|
||||||
conn, err := p.connectionFactory.DialURL(p.configuration.URL, p.dialOpts)
|
conn, err := p.connectionFactory.DialURL(p.configuration.URL, p.dialOpts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -2,6 +2,7 @@ package authentication
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/go-ldap/ldap/v3"
|
"github.com/go-ldap/ldap/v3"
|
||||||
|
@ -10,6 +11,7 @@ import (
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/configuration/schema"
|
"github.com/authelia/authelia/internal/configuration/schema"
|
||||||
|
"github.com/authelia/authelia/internal/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestShouldCreateRawConnectionWhenSchemeIsLDAP(t *testing.T) {
|
func TestShouldCreateRawConnectionWhenSchemeIsLDAP(t *testing.T) {
|
||||||
|
@ -19,7 +21,7 @@ func TestShouldCreateRawConnectionWhenSchemeIsLDAP(t *testing.T) {
|
||||||
mockFactory := NewMockLDAPConnectionFactory(ctrl)
|
mockFactory := NewMockLDAPConnectionFactory(ctrl)
|
||||||
mockConn := NewMockLDAPConnection(ctrl)
|
mockConn := NewMockLDAPConnection(ctrl)
|
||||||
|
|
||||||
ldapClient := NewLDAPUserProviderWithFactory(
|
ldapClient := newLDAPUserProvider(
|
||||||
schema.LDAPAuthenticationBackendConfiguration{
|
schema.LDAPAuthenticationBackendConfiguration{
|
||||||
URL: "ldap://127.0.0.1:389",
|
URL: "ldap://127.0.0.1:389",
|
||||||
},
|
},
|
||||||
|
@ -46,7 +48,7 @@ func TestShouldCreateTLSConnectionWhenSchemeIsLDAPS(t *testing.T) {
|
||||||
mockFactory := NewMockLDAPConnectionFactory(ctrl)
|
mockFactory := NewMockLDAPConnectionFactory(ctrl)
|
||||||
mockConn := NewMockLDAPConnection(ctrl)
|
mockConn := NewMockLDAPConnection(ctrl)
|
||||||
|
|
||||||
ldapClient := NewLDAPUserProviderWithFactory(
|
ldapClient := newLDAPUserProvider(
|
||||||
schema.LDAPAuthenticationBackendConfiguration{
|
schema.LDAPAuthenticationBackendConfiguration{
|
||||||
URL: "ldaps://127.0.0.1:389",
|
URL: "ldaps://127.0.0.1:389",
|
||||||
},
|
},
|
||||||
|
@ -72,7 +74,7 @@ func TestEscapeSpecialCharsFromUserInput(t *testing.T) {
|
||||||
|
|
||||||
mockFactory := NewMockLDAPConnectionFactory(ctrl)
|
mockFactory := NewMockLDAPConnectionFactory(ctrl)
|
||||||
|
|
||||||
ldapClient := NewLDAPUserProviderWithFactory(
|
ldapClient := newLDAPUserProvider(
|
||||||
schema.LDAPAuthenticationBackendConfiguration{
|
schema.LDAPAuthenticationBackendConfiguration{
|
||||||
URL: "ldaps://127.0.0.1:389",
|
URL: "ldaps://127.0.0.1:389",
|
||||||
},
|
},
|
||||||
|
@ -103,7 +105,7 @@ func TestEscapeSpecialCharsInGroupsFilter(t *testing.T) {
|
||||||
|
|
||||||
mockFactory := NewMockLDAPConnectionFactory(ctrl)
|
mockFactory := NewMockLDAPConnectionFactory(ctrl)
|
||||||
|
|
||||||
ldapClient := NewLDAPUserProviderWithFactory(
|
ldapClient := newLDAPUserProvider(
|
||||||
schema.LDAPAuthenticationBackendConfiguration{
|
schema.LDAPAuthenticationBackendConfiguration{
|
||||||
URL: "ldaps://127.0.0.1:389",
|
URL: "ldaps://127.0.0.1:389",
|
||||||
GroupsFilter: "(|(member={dn})(uid={username})(uid={input}))",
|
GroupsFilter: "(|(member={dn})(uid={username})(uid={input}))",
|
||||||
|
@ -125,6 +127,210 @@ func TestEscapeSpecialCharsInGroupsFilter(t *testing.T) {
|
||||||
assert.Equal(t, "(|(member=cn=john \\28external\\29,dc=example,dc=com)(uid=john)(uid=john\\#\\=\\28abc\\,def\\29))", filter)
|
assert.Equal(t, "(|(member=cn=john \\28external\\29,dc=example,dc=com)(uid=john)(uid=john\\#\\=\\28abc\\,def\\29))", filter)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ExtendedSearchRequestMatcher struct {
|
||||||
|
filter string
|
||||||
|
baseDN string
|
||||||
|
scope int
|
||||||
|
derefAliases int
|
||||||
|
typesOnly bool
|
||||||
|
attributes []string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewExtendedSearchRequestMatcher(filter, base string, scope, derefAliases int, typesOnly bool, attributes []string) *ExtendedSearchRequestMatcher {
|
||||||
|
return &ExtendedSearchRequestMatcher{filter, base, scope, derefAliases, typesOnly, attributes}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *ExtendedSearchRequestMatcher) Matches(x interface{}) bool {
|
||||||
|
sr := x.(*ldap.SearchRequest)
|
||||||
|
|
||||||
|
if e.filter != sr.Filter || e.baseDN != sr.BaseDN || e.scope != sr.Scope || e.derefAliases != sr.DerefAliases ||
|
||||||
|
e.typesOnly != sr.TypesOnly || utils.IsStringSlicesDifferent(e.attributes, sr.Attributes) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *ExtendedSearchRequestMatcher) String() string {
|
||||||
|
return fmt.Sprintf("baseDN: %s, filter %s", e.baseDN, e.filter)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestShouldCheckLDAPServerExtensions(t *testing.T) {
|
||||||
|
ctrl := gomock.NewController(t)
|
||||||
|
defer ctrl.Finish()
|
||||||
|
|
||||||
|
mockFactory := NewMockLDAPConnectionFactory(ctrl)
|
||||||
|
mockConn := NewMockLDAPConnection(ctrl)
|
||||||
|
|
||||||
|
ldapClient := newLDAPUserProvider(
|
||||||
|
schema.LDAPAuthenticationBackendConfiguration{
|
||||||
|
URL: "ldap://127.0.0.1:389",
|
||||||
|
User: "cn=admin,dc=example,dc=com",
|
||||||
|
UsersFilter: "(|({username_attribute}={input})({mail_attribute}={input}))",
|
||||||
|
UsernameAttribute: "uid",
|
||||||
|
MailAttribute: "mail",
|
||||||
|
DisplayNameAttribute: "displayname",
|
||||||
|
Password: "password",
|
||||||
|
AdditionalUsersDN: "ou=users",
|
||||||
|
BaseDN: "dc=example,dc=com",
|
||||||
|
},
|
||||||
|
nil,
|
||||||
|
mockFactory)
|
||||||
|
|
||||||
|
mockFactory.EXPECT().
|
||||||
|
DialURL(gomock.Eq("ldap://127.0.0.1:389"), gomock.Any()).
|
||||||
|
Return(mockConn, nil)
|
||||||
|
|
||||||
|
mockConn.EXPECT().
|
||||||
|
Bind(gomock.Eq("cn=admin,dc=example,dc=com"), gomock.Eq("password")).
|
||||||
|
Return(nil)
|
||||||
|
|
||||||
|
mockConn.EXPECT().
|
||||||
|
Search(NewExtendedSearchRequestMatcher("(objectClass=*)", "", ldap.ScopeBaseObject, ldap.NeverDerefAliases, false, []string{ldapSupportedExtensionAttribute})).
|
||||||
|
Return(&ldap.SearchResult{
|
||||||
|
Entries: []*ldap.Entry{
|
||||||
|
{
|
||||||
|
DN: "",
|
||||||
|
Attributes: []*ldap.EntryAttribute{
|
||||||
|
{
|
||||||
|
Name: ldapSupportedExtensionAttribute,
|
||||||
|
Values: []string{ldapOIDPasswdModifyExtension},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, nil)
|
||||||
|
|
||||||
|
err := ldapClient.checkServer()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
assert.True(t, ldapClient.supportExtensionPasswdModify)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestShouldNotEnablePasswdModifyExtension(t *testing.T) {
|
||||||
|
ctrl := gomock.NewController(t)
|
||||||
|
defer ctrl.Finish()
|
||||||
|
|
||||||
|
mockFactory := NewMockLDAPConnectionFactory(ctrl)
|
||||||
|
mockConn := NewMockLDAPConnection(ctrl)
|
||||||
|
|
||||||
|
ldapClient := newLDAPUserProvider(
|
||||||
|
schema.LDAPAuthenticationBackendConfiguration{
|
||||||
|
URL: "ldap://127.0.0.1:389",
|
||||||
|
User: "cn=admin,dc=example,dc=com",
|
||||||
|
UsersFilter: "(|({username_attribute}={input})({mail_attribute}={input}))",
|
||||||
|
UsernameAttribute: "uid",
|
||||||
|
MailAttribute: "mail",
|
||||||
|
DisplayNameAttribute: "displayname",
|
||||||
|
Password: "password",
|
||||||
|
AdditionalUsersDN: "ou=users",
|
||||||
|
BaseDN: "dc=example,dc=com",
|
||||||
|
},
|
||||||
|
nil,
|
||||||
|
mockFactory)
|
||||||
|
|
||||||
|
mockFactory.EXPECT().
|
||||||
|
DialURL(gomock.Eq("ldap://127.0.0.1:389"), gomock.Any()).
|
||||||
|
Return(mockConn, nil)
|
||||||
|
|
||||||
|
mockConn.EXPECT().
|
||||||
|
Bind(gomock.Eq("cn=admin,dc=example,dc=com"), gomock.Eq("password")).
|
||||||
|
Return(nil)
|
||||||
|
|
||||||
|
mockConn.EXPECT().
|
||||||
|
Search(NewExtendedSearchRequestMatcher("(objectClass=*)", "", ldap.ScopeBaseObject, ldap.NeverDerefAliases, false, []string{ldapSupportedExtensionAttribute})).
|
||||||
|
Return(&ldap.SearchResult{
|
||||||
|
Entries: []*ldap.Entry{
|
||||||
|
{
|
||||||
|
DN: "",
|
||||||
|
Attributes: []*ldap.EntryAttribute{
|
||||||
|
{
|
||||||
|
Name: ldapSupportedExtensionAttribute,
|
||||||
|
Values: []string{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, nil)
|
||||||
|
|
||||||
|
err := ldapClient.checkServer()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
assert.False(t, ldapClient.supportExtensionPasswdModify)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestShouldReturnCheckServerConnectError(t *testing.T) {
|
||||||
|
ctrl := gomock.NewController(t)
|
||||||
|
defer ctrl.Finish()
|
||||||
|
|
||||||
|
mockFactory := NewMockLDAPConnectionFactory(ctrl)
|
||||||
|
mockConn := NewMockLDAPConnection(ctrl)
|
||||||
|
|
||||||
|
ldapClient := newLDAPUserProvider(
|
||||||
|
schema.LDAPAuthenticationBackendConfiguration{
|
||||||
|
URL: "ldap://127.0.0.1:389",
|
||||||
|
User: "cn=admin,dc=example,dc=com",
|
||||||
|
UsersFilter: "(|({username_attribute}={input})({mail_attribute}={input}))",
|
||||||
|
UsernameAttribute: "uid",
|
||||||
|
MailAttribute: "mail",
|
||||||
|
DisplayNameAttribute: "displayname",
|
||||||
|
Password: "password",
|
||||||
|
AdditionalUsersDN: "ou=users",
|
||||||
|
BaseDN: "dc=example,dc=com",
|
||||||
|
},
|
||||||
|
nil,
|
||||||
|
mockFactory)
|
||||||
|
|
||||||
|
mockFactory.EXPECT().
|
||||||
|
DialURL(gomock.Eq("ldap://127.0.0.1:389"), gomock.Any()).
|
||||||
|
Return(mockConn, errors.New("could not connect"))
|
||||||
|
|
||||||
|
err := ldapClient.checkServer()
|
||||||
|
assert.EqualError(t, err, "could not connect")
|
||||||
|
|
||||||
|
assert.False(t, ldapClient.supportExtensionPasswdModify)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestShouldReturnCheckServerSearchError(t *testing.T) {
|
||||||
|
ctrl := gomock.NewController(t)
|
||||||
|
defer ctrl.Finish()
|
||||||
|
|
||||||
|
mockFactory := NewMockLDAPConnectionFactory(ctrl)
|
||||||
|
mockConn := NewMockLDAPConnection(ctrl)
|
||||||
|
|
||||||
|
ldapClient := newLDAPUserProvider(
|
||||||
|
schema.LDAPAuthenticationBackendConfiguration{
|
||||||
|
URL: "ldap://127.0.0.1:389",
|
||||||
|
User: "cn=admin,dc=example,dc=com",
|
||||||
|
UsersFilter: "(|({username_attribute}={input})({mail_attribute}={input}))",
|
||||||
|
UsernameAttribute: "uid",
|
||||||
|
MailAttribute: "mail",
|
||||||
|
DisplayNameAttribute: "displayname",
|
||||||
|
Password: "password",
|
||||||
|
AdditionalUsersDN: "ou=users",
|
||||||
|
BaseDN: "dc=example,dc=com",
|
||||||
|
},
|
||||||
|
nil,
|
||||||
|
mockFactory)
|
||||||
|
|
||||||
|
mockFactory.EXPECT().
|
||||||
|
DialURL(gomock.Eq("ldap://127.0.0.1:389"), gomock.Any()).
|
||||||
|
Return(mockConn, nil)
|
||||||
|
|
||||||
|
mockConn.EXPECT().
|
||||||
|
Bind(gomock.Eq("cn=admin,dc=example,dc=com"), gomock.Eq("password")).
|
||||||
|
Return(nil)
|
||||||
|
|
||||||
|
mockConn.EXPECT().
|
||||||
|
Search(NewExtendedSearchRequestMatcher("(objectClass=*)", "", ldap.ScopeBaseObject, ldap.NeverDerefAliases, false, []string{ldapSupportedExtensionAttribute})).
|
||||||
|
Return(nil, errors.New("could not perform the search"))
|
||||||
|
|
||||||
|
err := ldapClient.checkServer()
|
||||||
|
assert.EqualError(t, err, "could not perform the search")
|
||||||
|
|
||||||
|
assert.False(t, ldapClient.supportExtensionPasswdModify)
|
||||||
|
}
|
||||||
|
|
||||||
type SearchRequestMatcher struct {
|
type SearchRequestMatcher struct {
|
||||||
expected string
|
expected string
|
||||||
}
|
}
|
||||||
|
@ -149,7 +355,7 @@ func TestShouldEscapeUserInput(t *testing.T) {
|
||||||
mockFactory := NewMockLDAPConnectionFactory(ctrl)
|
mockFactory := NewMockLDAPConnectionFactory(ctrl)
|
||||||
mockConn := NewMockLDAPConnection(ctrl)
|
mockConn := NewMockLDAPConnection(ctrl)
|
||||||
|
|
||||||
ldapClient := NewLDAPUserProviderWithFactory(
|
ldapClient := newLDAPUserProvider(
|
||||||
schema.LDAPAuthenticationBackendConfiguration{
|
schema.LDAPAuthenticationBackendConfiguration{
|
||||||
URL: "ldap://127.0.0.1:389",
|
URL: "ldap://127.0.0.1:389",
|
||||||
User: "cn=admin,dc=example,dc=com",
|
User: "cn=admin,dc=example,dc=com",
|
||||||
|
@ -181,7 +387,7 @@ func TestShouldCombineUsernameFilterAndUsersFilter(t *testing.T) {
|
||||||
mockFactory := NewMockLDAPConnectionFactory(ctrl)
|
mockFactory := NewMockLDAPConnectionFactory(ctrl)
|
||||||
mockConn := NewMockLDAPConnection(ctrl)
|
mockConn := NewMockLDAPConnection(ctrl)
|
||||||
|
|
||||||
ldapClient := NewLDAPUserProviderWithFactory(
|
ldapClient := newLDAPUserProvider(
|
||||||
schema.LDAPAuthenticationBackendConfiguration{
|
schema.LDAPAuthenticationBackendConfiguration{
|
||||||
URL: "ldap://127.0.0.1:389",
|
URL: "ldap://127.0.0.1:389",
|
||||||
User: "cn=admin,dc=example,dc=com",
|
User: "cn=admin,dc=example,dc=com",
|
||||||
|
@ -226,7 +432,7 @@ func TestShouldNotCrashWhenGroupsAreNotRetrievedFromLDAP(t *testing.T) {
|
||||||
mockFactory := NewMockLDAPConnectionFactory(ctrl)
|
mockFactory := NewMockLDAPConnectionFactory(ctrl)
|
||||||
mockConn := NewMockLDAPConnection(ctrl)
|
mockConn := NewMockLDAPConnection(ctrl)
|
||||||
|
|
||||||
ldapClient := NewLDAPUserProviderWithFactory(
|
ldapClient := newLDAPUserProvider(
|
||||||
schema.LDAPAuthenticationBackendConfiguration{
|
schema.LDAPAuthenticationBackendConfiguration{
|
||||||
URL: "ldap://127.0.0.1:389",
|
URL: "ldap://127.0.0.1:389",
|
||||||
User: "cn=admin,dc=example,dc=com",
|
User: "cn=admin,dc=example,dc=com",
|
||||||
|
@ -297,7 +503,7 @@ func TestShouldNotCrashWhenEmailsAreNotRetrievedFromLDAP(t *testing.T) {
|
||||||
mockFactory := NewMockLDAPConnectionFactory(ctrl)
|
mockFactory := NewMockLDAPConnectionFactory(ctrl)
|
||||||
mockConn := NewMockLDAPConnection(ctrl)
|
mockConn := NewMockLDAPConnection(ctrl)
|
||||||
|
|
||||||
ldapClient := NewLDAPUserProviderWithFactory(
|
ldapClient := newLDAPUserProvider(
|
||||||
schema.LDAPAuthenticationBackendConfiguration{
|
schema.LDAPAuthenticationBackendConfiguration{
|
||||||
URL: "ldap://127.0.0.1:389",
|
URL: "ldap://127.0.0.1:389",
|
||||||
User: "cn=admin,dc=example,dc=com",
|
User: "cn=admin,dc=example,dc=com",
|
||||||
|
@ -357,7 +563,7 @@ func TestShouldReturnUsernameFromLDAP(t *testing.T) {
|
||||||
mockFactory := NewMockLDAPConnectionFactory(ctrl)
|
mockFactory := NewMockLDAPConnectionFactory(ctrl)
|
||||||
mockConn := NewMockLDAPConnection(ctrl)
|
mockConn := NewMockLDAPConnection(ctrl)
|
||||||
|
|
||||||
ldapClient := NewLDAPUserProviderWithFactory(
|
ldapClient := newLDAPUserProvider(
|
||||||
schema.LDAPAuthenticationBackendConfiguration{
|
schema.LDAPAuthenticationBackendConfiguration{
|
||||||
URL: "ldap://127.0.0.1:389",
|
URL: "ldap://127.0.0.1:389",
|
||||||
User: "cn=admin,dc=example,dc=com",
|
User: "cn=admin,dc=example,dc=com",
|
||||||
|
@ -428,7 +634,7 @@ func TestShouldUpdateUserPassword(t *testing.T) {
|
||||||
mockFactory := NewMockLDAPConnectionFactory(ctrl)
|
mockFactory := NewMockLDAPConnectionFactory(ctrl)
|
||||||
mockConn := NewMockLDAPConnection(ctrl)
|
mockConn := NewMockLDAPConnection(ctrl)
|
||||||
|
|
||||||
ldapClient := NewLDAPUserProviderWithFactory(
|
ldapClient := newLDAPUserProvider(
|
||||||
schema.LDAPAuthenticationBackendConfiguration{
|
schema.LDAPAuthenticationBackendConfiguration{
|
||||||
URL: "ldap://127.0.0.1:389",
|
URL: "ldap://127.0.0.1:389",
|
||||||
User: "cn=admin,dc=example,dc=com",
|
User: "cn=admin,dc=example,dc=com",
|
||||||
|
@ -495,7 +701,7 @@ func TestShouldCheckValidUserPassword(t *testing.T) {
|
||||||
mockFactory := NewMockLDAPConnectionFactory(ctrl)
|
mockFactory := NewMockLDAPConnectionFactory(ctrl)
|
||||||
mockConn := NewMockLDAPConnection(ctrl)
|
mockConn := NewMockLDAPConnection(ctrl)
|
||||||
|
|
||||||
ldapClient := NewLDAPUserProviderWithFactory(
|
ldapClient := newLDAPUserProvider(
|
||||||
schema.LDAPAuthenticationBackendConfiguration{
|
schema.LDAPAuthenticationBackendConfiguration{
|
||||||
URL: "ldap://127.0.0.1:389",
|
URL: "ldap://127.0.0.1:389",
|
||||||
User: "cn=admin,dc=example,dc=com",
|
User: "cn=admin,dc=example,dc=com",
|
||||||
|
@ -563,7 +769,7 @@ func TestShouldCheckInvalidUserPassword(t *testing.T) {
|
||||||
mockFactory := NewMockLDAPConnectionFactory(ctrl)
|
mockFactory := NewMockLDAPConnectionFactory(ctrl)
|
||||||
mockConn := NewMockLDAPConnection(ctrl)
|
mockConn := NewMockLDAPConnection(ctrl)
|
||||||
|
|
||||||
ldapClient := NewLDAPUserProviderWithFactory(
|
ldapClient := newLDAPUserProvider(
|
||||||
schema.LDAPAuthenticationBackendConfiguration{
|
schema.LDAPAuthenticationBackendConfiguration{
|
||||||
URL: "ldap://127.0.0.1:389",
|
URL: "ldap://127.0.0.1:389",
|
||||||
User: "cn=admin,dc=example,dc=com",
|
User: "cn=admin,dc=example,dc=com",
|
||||||
|
@ -631,7 +837,7 @@ func TestShouldCallStartTLSWhenEnabled(t *testing.T) {
|
||||||
mockFactory := NewMockLDAPConnectionFactory(ctrl)
|
mockFactory := NewMockLDAPConnectionFactory(ctrl)
|
||||||
mockConn := NewMockLDAPConnection(ctrl)
|
mockConn := NewMockLDAPConnection(ctrl)
|
||||||
|
|
||||||
ldapClient := NewLDAPUserProviderWithFactory(
|
ldapClient := newLDAPUserProvider(
|
||||||
schema.LDAPAuthenticationBackendConfiguration{
|
schema.LDAPAuthenticationBackendConfiguration{
|
||||||
URL: "ldap://127.0.0.1:389",
|
URL: "ldap://127.0.0.1:389",
|
||||||
User: "cn=admin,dc=example,dc=com",
|
User: "cn=admin,dc=example,dc=com",
|
||||||
|
@ -705,7 +911,7 @@ func TestShouldParseDynamicConfiguration(t *testing.T) {
|
||||||
|
|
||||||
mockFactory := NewMockLDAPConnectionFactory(ctrl)
|
mockFactory := NewMockLDAPConnectionFactory(ctrl)
|
||||||
|
|
||||||
ldapClient := NewLDAPUserProviderWithFactory(
|
ldapClient := newLDAPUserProvider(
|
||||||
schema.LDAPAuthenticationBackendConfiguration{
|
schema.LDAPAuthenticationBackendConfiguration{
|
||||||
URL: "ldap://127.0.0.1:389",
|
URL: "ldap://127.0.0.1:389",
|
||||||
User: "cn=admin,dc=example,dc=com",
|
User: "cn=admin,dc=example,dc=com",
|
||||||
|
@ -736,7 +942,7 @@ func TestShouldCallStartTLSWithInsecureSkipVerifyWhenSkipVerifyTrue(t *testing.T
|
||||||
mockFactory := NewMockLDAPConnectionFactory(ctrl)
|
mockFactory := NewMockLDAPConnectionFactory(ctrl)
|
||||||
mockConn := NewMockLDAPConnection(ctrl)
|
mockConn := NewMockLDAPConnection(ctrl)
|
||||||
|
|
||||||
ldapClient := NewLDAPUserProviderWithFactory(
|
ldapClient := newLDAPUserProvider(
|
||||||
schema.LDAPAuthenticationBackendConfiguration{
|
schema.LDAPAuthenticationBackendConfiguration{
|
||||||
URL: "ldap://127.0.0.1:389",
|
URL: "ldap://127.0.0.1:389",
|
||||||
User: "cn=admin,dc=example,dc=com",
|
User: "cn=admin,dc=example,dc=com",
|
||||||
|
@ -814,7 +1020,7 @@ func TestShouldReturnLDAPSAlreadySecuredWhenStartTLSAttempted(t *testing.T) {
|
||||||
mockFactory := NewMockLDAPConnectionFactory(ctrl)
|
mockFactory := NewMockLDAPConnectionFactory(ctrl)
|
||||||
mockConn := NewMockLDAPConnection(ctrl)
|
mockConn := NewMockLDAPConnection(ctrl)
|
||||||
|
|
||||||
ldapClient := NewLDAPUserProviderWithFactory(
|
ldapClient := newLDAPUserProvider(
|
||||||
schema.LDAPAuthenticationBackendConfiguration{
|
schema.LDAPAuthenticationBackendConfiguration{
|
||||||
URL: "ldaps://127.0.0.1:389",
|
URL: "ldaps://127.0.0.1:389",
|
||||||
User: "cn=admin,dc=example,dc=com",
|
User: "cn=admin,dc=example,dc=com",
|
||||||
|
|
Loading…
Reference in New Issue