summaryrefslogtreecommitdiff
path: root/internal/authentication/ldap_user_provider_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/authentication/ldap_user_provider_test.go')
-rw-r--r--internal/authentication/ldap_user_provider_test.go857
1 files changed, 857 insertions, 0 deletions
diff --git a/internal/authentication/ldap_user_provider_test.go b/internal/authentication/ldap_user_provider_test.go
index 0918aee5a..04a37e5f2 100644
--- a/internal/authentication/ldap_user_provider_test.go
+++ b/internal/authentication/ldap_user_provider_test.go
@@ -3,6 +3,7 @@ package authentication
import (
"errors"
"fmt"
+ "net/url"
"testing"
"time"
@@ -11,6 +12,7 @@ import (
"github.com/stretchr/testify/require"
"go.uber.org/mock/gomock"
"golang.org/x/text/encoding/unicode"
+ "golang.org/x/text/language"
"github.com/authelia/authelia/v4/internal/clock"
"github.com/authelia/authelia/v4/internal/configuration/schema"
@@ -1046,6 +1048,7 @@ func TestShouldCombineUsernameFilterAndUsersFilter(t *testing.T) {
assert.EqualError(t, err, "user not found")
}
+//nolint:unparam
func createSearchResultWithAttributes(attributes ...*ldap.EntryAttribute) *ldap.SearchResult {
return &ldap.SearchResult{
Entries: []*ldap.Entry{
@@ -1162,6 +1165,731 @@ func TestShouldNotCrashWhenGroupsAreNotRetrievedFromLDAP(t *testing.T) {
assert.Equal(t, details.Username, "john")
}
+func TestLDAPUserProvider_GetDetailsExtended_ShouldPass(t *testing.T) {
+ ctrl := gomock.NewController(t)
+ defer ctrl.Finish()
+
+ mockFactory := NewMockLDAPClientFactory(ctrl)
+ mockClient := NewMockLDAPClient(ctrl)
+
+ provider := NewLDAPUserProviderWithFactory(
+ schema.AuthenticationBackendLDAP{
+ Address: testLDAPAddress,
+ User: "cn=admin,dc=example,dc=com",
+ Password: "password",
+ Attributes: schema.AuthenticationBackendLDAPAttributes{
+ Username: "uid",
+ Mail: "mail",
+ DisplayName: "displayName",
+ MemberOf: "memberOf",
+ StreetAddress: "street",
+ FamilyName: "sn",
+ MiddleName: "middle",
+ GivenName: "givenName",
+ Nickname: "nickname",
+ Gender: "gender",
+ Birthdate: "birthDate",
+ Website: "website",
+ Profile: "profile",
+ Picture: "picture",
+ ZoneInfo: "zoneinfo",
+ Locale: "locale",
+ PhoneNumber: "phone",
+ PhoneExtension: "ext",
+ Locality: "locality",
+ Region: "region",
+ PostalCode: "postCode",
+ Country: "c",
+ Extra: map[string]schema.AuthenticationBackendLDAPAttributesAttribute{
+ "exampleStr": {
+ AuthenticationBackendExtraAttribute: schema.AuthenticationBackendExtraAttribute{
+ MultiValued: false,
+ ValueType: ValueTypeString,
+ },
+ },
+ "exampleStrMV": {
+ AuthenticationBackendExtraAttribute: schema.AuthenticationBackendExtraAttribute{
+ MultiValued: true,
+ ValueType: ValueTypeString,
+ },
+ },
+ "exampleInt": {
+ Name: "exampleIntChangedAttributeName",
+ AuthenticationBackendExtraAttribute: schema.AuthenticationBackendExtraAttribute{
+ MultiValued: false,
+ ValueType: ValueTypeInteger,
+ },
+ },
+ "exampleIntMV": {
+ AuthenticationBackendExtraAttribute: schema.AuthenticationBackendExtraAttribute{
+ MultiValued: true,
+ ValueType: ValueTypeInteger,
+ },
+ },
+ "exampleBool": {
+ AuthenticationBackendExtraAttribute: schema.AuthenticationBackendExtraAttribute{
+ MultiValued: false,
+ ValueType: ValueTypeBoolean,
+ },
+ },
+ "exampleBoolMV": {
+ AuthenticationBackendExtraAttribute: schema.AuthenticationBackendExtraAttribute{
+ MultiValued: true,
+ ValueType: ValueTypeBoolean,
+ },
+ },
+ "exampleEmptyStringInt": {
+ AuthenticationBackendExtraAttribute: schema.AuthenticationBackendExtraAttribute{
+ MultiValued: false,
+ ValueType: ValueTypeInteger,
+ },
+ },
+ "exampleEmptyStringBoolean": {
+ AuthenticationBackendExtraAttribute: schema.AuthenticationBackendExtraAttribute{
+ MultiValued: false,
+ ValueType: ValueTypeBoolean,
+ },
+ },
+ },
+ },
+ UsersFilter: "uid={input}",
+ AdditionalUsersDN: "ou=users",
+ BaseDN: "dc=example,dc=com",
+ PermitReferrals: true,
+ },
+ false,
+ nil,
+ mockFactory)
+
+ dialURL := mockFactory.EXPECT().
+ DialURL(gomock.Eq("ldap://127.0.0.1:389"), gomock.Any()).
+ Return(mockClient, nil)
+
+ connBind := mockClient.EXPECT().
+ Bind(gomock.Eq("cn=admin,dc=example,dc=com"), gomock.Eq("password")).
+ Return(nil)
+
+ connClose := mockClient.EXPECT().Close()
+
+ searchProfile := mockClient.EXPECT().
+ Search(gomock.Any()).
+ Return(&ldap.SearchResult{
+ Entries: []*ldap.Entry{
+ {
+ DN: "uid=john,dc=example,dc=com",
+ Attributes: []*ldap.EntryAttribute{
+ {
+ Name: "uid",
+ Values: []string{"john"},
+ },
+ {
+ Name: "mail",
+ Values: []string{},
+ },
+ {
+ Name: "displayName",
+ Values: []string{},
+ },
+ {
+ Name: "memberOf",
+ Values: []string{},
+ },
+ {
+ Name: "street",
+ Values: []string{"123 Banksia Ln"},
+ },
+ {
+ Name: "sn",
+ Values: []string{"Smith"},
+ },
+ {
+ Name: "middle",
+ Values: []string{"Jacob"},
+ },
+ {
+ Name: "givenName",
+ Values: []string{"John"},
+ },
+ {
+ Name: "nickname",
+ Values: []string{"Johny"},
+ },
+ {
+ Name: "gender",
+ Values: []string{"male"},
+ },
+ {
+ Name: "birthDate",
+ Values: []string{"2/2/2021"},
+ },
+ {
+ Name: "website",
+ Values: []string{"https://authelia.com"},
+ },
+ {
+ Name: "profile",
+ Values: []string{"https://authelia.com/profile/jsmith.html"},
+ },
+ {
+ Name: "picture",
+ Values: []string{"https://authelia.com/picture/jsmith.jpg"},
+ },
+ {
+ Name: "zoneinfo",
+ Values: []string{"Australia/Melbourne"},
+ },
+ {
+ Name: "locale",
+ Values: []string{"en-AU"},
+ },
+ {
+ Name: "phone",
+ Values: []string{"+1 (604) 555-1234"},
+ },
+ {
+ Name: "ext",
+ Values: []string{"5678"},
+ },
+ {
+ Name: "locality",
+ Values: []string{"Melbourne"},
+ },
+ {
+ Name: "region",
+ Values: []string{"Victoria"},
+ },
+ {
+ Name: "postCode",
+ Values: []string{"2000"},
+ },
+ {
+ Name: "c",
+ Values: []string{"Australia"},
+ },
+ {
+ Name: "exampleStr",
+ Values: []string{"abc"},
+ },
+ {
+ Name: "exampleStrMV",
+ Values: []string{"abc", "123"},
+ },
+ {
+ Name: "exampleInt",
+ Values: []string{"123"},
+ },
+ {
+ Name: "exampleIntMV",
+ Values: []string{"1023879012731.5", "123"},
+ },
+ {
+ Name: "exampleBool",
+ Values: []string{"true"},
+ },
+ {
+ Name: "exampleBoolMV",
+ Values: []string{"true", "false"},
+ },
+ {
+ Name: "exampleEmptyStringInt",
+ Values: []string{""},
+ },
+ {
+ Name: "exampleEmptyStringBoolean",
+ Values: []string{""},
+ },
+ },
+ },
+ },
+ }, nil)
+
+ searchGroup := mockClient.EXPECT().Search(gomock.Any()).Return(createSearchResultWithAttributes(), nil)
+
+ gomock.InOrder(dialURL, connBind, searchProfile, searchGroup, connClose)
+
+ enAU := language.MustParse("en-AU")
+ website, _ := url.Parse("https://authelia.com")
+ profile, _ := url.Parse("https://authelia.com/profile/jsmith.html")
+ picture, _ := url.Parse("https://authelia.com/picture/jsmith.jpg")
+
+ details, err := provider.GetDetailsExtended("john")
+ assert.Equal(t,
+ &UserDetailsExtended{
+ GivenName: "John",
+ FamilyName: "Smith",
+ MiddleName: "Jacob",
+ Nickname: "Johny",
+ Profile: profile,
+ Picture: picture,
+ Website: website,
+ Gender: "male",
+ Birthdate: "2/2/2021",
+ ZoneInfo: "Australia/Melbourne",
+ Locale: &enAU,
+ PhoneNumber: "+1 (604) 555-1234",
+ PhoneExtension: "5678",
+ Address: &UserDetailsAddress{
+ StreetAddress: "123 Banksia Ln",
+ Locality: "Melbourne",
+ Region: "Victoria",
+ PostalCode: "2000",
+ Country: "Australia",
+ },
+ Extra: map[string]any{
+ "exampleStr": "abc",
+ "exampleStrMV": []any{"abc", "123"},
+ "exampleIntChangedAttributeName": float64(123),
+ "exampleIntMV": []any{1023879012731.5, float64(123)},
+ "exampleBool": true,
+ "exampleBoolMV": []any{true, false},
+ },
+ UserDetails: &UserDetails{Username: "john", DisplayName: "", Emails: []string{}, Groups: []string(nil)},
+ }, details)
+
+ assert.NoError(t, err)
+}
+
+func TestLDAPUserProvider_GetDetailsExtended_ShouldParseError(t *testing.T) {
+ testCases := []struct {
+ name string
+ valueType string
+ multiValued bool
+ err string
+ }{
+ {
+ "ShouldHandleBadInteger",
+ ValueTypeInteger,
+ false,
+ "cannot parse 'example' with value 'abc' as integer: strconv.ParseFloat: parsing \"abc\": invalid syntax",
+ },
+ {
+ "ShouldHandleBadIntegerMV",
+ ValueTypeInteger,
+ true,
+ "cannot parse 'example' with value 'abc' as integer: strconv.ParseFloat: parsing \"abc\": invalid syntax",
+ },
+ {
+ "ShouldHandleBadBoolean",
+ ValueTypeBoolean,
+ false,
+ "cannot parse 'example' with value 'abc' as boolean: strconv.ParseBool: parsing \"abc\": invalid syntax",
+ },
+ {
+ "ShouldHandleBadBooleanMV",
+ ValueTypeBoolean,
+ true,
+ "cannot parse 'example' with value 'abc' as boolean: strconv.ParseBool: parsing \"abc\": invalid syntax",
+ },
+ }
+
+ for _, tc := range testCases {
+ t.Run(tc.name, func(t *testing.T) {
+ ctrl := gomock.NewController(t)
+ defer ctrl.Finish()
+
+ mockFactory := NewMockLDAPClientFactory(ctrl)
+ mockClient := NewMockLDAPClient(ctrl)
+
+ provider := NewLDAPUserProviderWithFactory(
+ schema.AuthenticationBackendLDAP{
+ Address: testLDAPAddress,
+ User: "cn=admin,dc=example,dc=com",
+ Password: "password",
+ Attributes: schema.AuthenticationBackendLDAPAttributes{
+ Username: "uid",
+ Mail: "mail",
+ DisplayName: "displayName",
+ MemberOf: "memberOf",
+ StreetAddress: "street",
+ Extra: map[string]schema.AuthenticationBackendLDAPAttributesAttribute{
+ "example": {
+ AuthenticationBackendExtraAttribute: schema.AuthenticationBackendExtraAttribute{
+ MultiValued: tc.multiValued,
+ ValueType: tc.valueType,
+ },
+ },
+ },
+ },
+ UsersFilter: "uid={input}",
+ AdditionalUsersDN: "ou=users",
+ BaseDN: "dc=example,dc=com",
+ PermitReferrals: true,
+ },
+ false,
+ nil,
+ mockFactory)
+
+ dialURL := mockFactory.EXPECT().
+ DialURL(gomock.Eq("ldap://127.0.0.1:389"), gomock.Any()).
+ Return(mockClient, nil)
+
+ connBind := mockClient.EXPECT().
+ Bind(gomock.Eq("cn=admin,dc=example,dc=com"), gomock.Eq("password")).
+ Return(nil)
+
+ connClose := mockClient.EXPECT().Close()
+
+ searchProfile := mockClient.EXPECT().
+ Search(gomock.Any()).
+ Return(&ldap.SearchResult{
+ Entries: []*ldap.Entry{
+ {
+ DN: "uid=john,dc=example,dc=com",
+ Attributes: []*ldap.EntryAttribute{
+ {
+ Name: "uid",
+ Values: []string{"john"},
+ },
+ {
+ Name: "mail",
+ Values: []string{},
+ },
+ {
+ Name: "displayName",
+ Values: []string{},
+ },
+ {
+ Name: "memberOf",
+ Values: []string{},
+ },
+ {
+ Name: "street",
+ Values: []string{"123 Banksia Ln"},
+ },
+ {
+ Name: "example",
+ Values: []string{"abc"},
+ },
+ },
+ },
+ },
+ }, nil)
+
+ gomock.InOrder(dialURL, connBind, searchProfile, connClose)
+
+ details, err := provider.GetDetailsExtended("john")
+ assert.Nil(t, details)
+ assert.EqualError(t, err, tc.err)
+ })
+ }
+}
+
+func TestLDAPUserProvider_GetDetailsExtended_ShouldErrorBadPictureURL(t *testing.T) {
+ ctrl := gomock.NewController(t)
+ defer ctrl.Finish()
+
+ mockFactory := NewMockLDAPClientFactory(ctrl)
+ mockClient := NewMockLDAPClient(ctrl)
+
+ provider := NewLDAPUserProviderWithFactory(
+ schema.AuthenticationBackendLDAP{
+ Address: testLDAPAddress,
+ User: "cn=admin,dc=example,dc=com",
+ Password: "password",
+ Attributes: schema.AuthenticationBackendLDAPAttributes{
+ Username: "uid",
+ Mail: "mail",
+ DisplayName: "displayName",
+ MemberOf: "memberOf",
+ Picture: "photoURL",
+ },
+ UsersFilter: "uid={input}",
+ AdditionalUsersDN: "ou=users",
+ BaseDN: "dc=example,dc=com",
+ PermitReferrals: true,
+ },
+ false,
+ nil,
+ mockFactory)
+
+ dialURL := mockFactory.EXPECT().
+ DialURL(gomock.Eq("ldap://127.0.0.1:389"), gomock.Any()).
+ Return(mockClient, nil)
+
+ connBind := mockClient.EXPECT().
+ Bind(gomock.Eq("cn=admin,dc=example,dc=com"), gomock.Eq("password")).
+ Return(nil)
+
+ connClose := mockClient.EXPECT().Close()
+
+ searchProfile := mockClient.EXPECT().
+ Search(gomock.Any()).
+ Return(&ldap.SearchResult{
+ Entries: []*ldap.Entry{
+ {
+ DN: "uid=john,dc=example,dc=com",
+ Attributes: []*ldap.EntryAttribute{
+ {
+ Name: "uid",
+ Values: []string{"john"},
+ },
+ {
+ Name: "mail",
+ Values: []string{},
+ },
+ {
+ Name: "displayName",
+ Values: []string{},
+ },
+ {
+ Name: "memberOf",
+ Values: []string{},
+ },
+ {
+ Name: "photoURL",
+ Values: []string{"bad_+URL"},
+ },
+ },
+ },
+ },
+ }, nil)
+
+ searchGroup := mockClient.EXPECT().Search(gomock.Any()).Return(createSearchResultWithAttributes(), nil)
+
+ gomock.InOrder(dialURL, connBind, searchProfile, searchGroup, connClose)
+
+ details, err := provider.GetDetailsExtended("john")
+ assert.Nil(t, details)
+ assert.EqualError(t, err, "error occurred parsing user details for 'john': failed to parse the picture attribute 'photoURL' with value 'bad_+URL': parse \"bad_+URL\": invalid URI for request")
+}
+
+func TestLDAPUserProvider_GetDetailsExtended_ShouldErrorBadProfileURL(t *testing.T) {
+ ctrl := gomock.NewController(t)
+ defer ctrl.Finish()
+
+ mockFactory := NewMockLDAPClientFactory(ctrl)
+ mockClient := NewMockLDAPClient(ctrl)
+
+ provider := NewLDAPUserProviderWithFactory(
+ schema.AuthenticationBackendLDAP{
+ Address: testLDAPAddress,
+ User: "cn=admin,dc=example,dc=com",
+ Password: "password",
+ Attributes: schema.AuthenticationBackendLDAPAttributes{
+ Username: "uid",
+ Mail: "mail",
+ DisplayName: "displayName",
+ MemberOf: "memberOf",
+ Profile: "profile",
+ },
+ UsersFilter: "uid={input}",
+ AdditionalUsersDN: "ou=users",
+ BaseDN: "dc=example,dc=com",
+ PermitReferrals: true,
+ },
+ false,
+ nil,
+ mockFactory)
+
+ dialURL := mockFactory.EXPECT().
+ DialURL(gomock.Eq("ldap://127.0.0.1:389"), gomock.Any()).
+ Return(mockClient, nil)
+
+ connBind := mockClient.EXPECT().
+ Bind(gomock.Eq("cn=admin,dc=example,dc=com"), gomock.Eq("password")).
+ Return(nil)
+
+ connClose := mockClient.EXPECT().Close()
+
+ searchProfile := mockClient.EXPECT().
+ Search(gomock.Any()).
+ Return(&ldap.SearchResult{
+ Entries: []*ldap.Entry{
+ {
+ DN: "uid=john,dc=example,dc=com",
+ Attributes: []*ldap.EntryAttribute{
+ {
+ Name: "uid",
+ Values: []string{"john"},
+ },
+ {
+ Name: "mail",
+ Values: []string{},
+ },
+ {
+ Name: "displayName",
+ Values: []string{},
+ },
+ {
+ Name: "memberOf",
+ Values: []string{},
+ },
+ {
+ Name: "profile",
+ Values: []string{"bad_+URL"},
+ },
+ },
+ },
+ },
+ }, nil)
+
+ searchGroup := mockClient.EXPECT().Search(gomock.Any()).Return(createSearchResultWithAttributes(), nil)
+
+ gomock.InOrder(dialURL, connBind, searchProfile, searchGroup, connClose)
+
+ details, err := provider.GetDetailsExtended("john")
+ assert.Nil(t, details)
+ assert.EqualError(t, err, "error occurred parsing user details for 'john': failed to parse the profile attribute 'profile' with value 'bad_+URL': parse \"bad_+URL\": invalid URI for request")
+}
+
+func TestLDAPUserProvider_GetDetailsExtended_ShouldErrorBadWebsiteURL(t *testing.T) {
+ ctrl := gomock.NewController(t)
+ defer ctrl.Finish()
+
+ mockFactory := NewMockLDAPClientFactory(ctrl)
+ mockClient := NewMockLDAPClient(ctrl)
+
+ provider := NewLDAPUserProviderWithFactory(
+ schema.AuthenticationBackendLDAP{
+ Address: testLDAPAddress,
+ User: "cn=admin,dc=example,dc=com",
+ Password: "password",
+ Attributes: schema.AuthenticationBackendLDAPAttributes{
+ Username: "uid",
+ Mail: "mail",
+ DisplayName: "displayName",
+ MemberOf: "memberOf",
+ Website: "www",
+ },
+ UsersFilter: "uid={input}",
+ AdditionalUsersDN: "ou=users",
+ BaseDN: "dc=example,dc=com",
+ PermitReferrals: true,
+ },
+ false,
+ nil,
+ mockFactory)
+
+ dialURL := mockFactory.EXPECT().
+ DialURL(gomock.Eq("ldap://127.0.0.1:389"), gomock.Any()).
+ Return(mockClient, nil)
+
+ connBind := mockClient.EXPECT().
+ Bind(gomock.Eq("cn=admin,dc=example,dc=com"), gomock.Eq("password")).
+ Return(nil)
+
+ connClose := mockClient.EXPECT().Close()
+
+ searchProfile := mockClient.EXPECT().
+ Search(gomock.Any()).
+ Return(&ldap.SearchResult{
+ Entries: []*ldap.Entry{
+ {
+ DN: "uid=john,dc=example,dc=com",
+ Attributes: []*ldap.EntryAttribute{
+ {
+ Name: "uid",
+ Values: []string{"john"},
+ },
+ {
+ Name: "mail",
+ Values: []string{},
+ },
+ {
+ Name: "displayName",
+ Values: []string{},
+ },
+ {
+ Name: "memberOf",
+ Values: []string{},
+ },
+ {
+ Name: "www",
+ Values: []string{"bad_+URL"},
+ },
+ },
+ },
+ },
+ }, nil)
+
+ searchGroup := mockClient.EXPECT().Search(gomock.Any()).Return(createSearchResultWithAttributes(), nil)
+
+ gomock.InOrder(dialURL, connBind, searchProfile, searchGroup, connClose)
+
+ details, err := provider.GetDetailsExtended("john")
+ assert.Nil(t, details)
+ assert.EqualError(t, err, "error occurred parsing user details for 'john': failed to parse the website attribute 'www' with value 'bad_+URL': parse \"bad_+URL\": invalid URI for request")
+}
+
+func TestLDAPUserProvider_GetDetailsExtended_ShouldErrorBadLocale(t *testing.T) {
+ ctrl := gomock.NewController(t)
+ defer ctrl.Finish()
+
+ mockFactory := NewMockLDAPClientFactory(ctrl)
+ mockClient := NewMockLDAPClient(ctrl)
+
+ provider := NewLDAPUserProviderWithFactory(
+ schema.AuthenticationBackendLDAP{
+ Address: testLDAPAddress,
+ User: "cn=admin,dc=example,dc=com",
+ Password: "password",
+ Attributes: schema.AuthenticationBackendLDAPAttributes{
+ Username: "uid",
+ Mail: "mail",
+ DisplayName: "displayName",
+ MemberOf: "memberOf",
+ Locale: "locale",
+ },
+ UsersFilter: "uid={input}",
+ AdditionalUsersDN: "ou=users",
+ BaseDN: "dc=example,dc=com",
+ PermitReferrals: true,
+ },
+ false,
+ nil,
+ mockFactory)
+
+ dialURL := mockFactory.EXPECT().
+ DialURL(gomock.Eq("ldap://127.0.0.1:389"), gomock.Any()).
+ Return(mockClient, nil)
+
+ connBind := mockClient.EXPECT().
+ Bind(gomock.Eq("cn=admin,dc=example,dc=com"), gomock.Eq("password")).
+ Return(nil)
+
+ connClose := mockClient.EXPECT().Close()
+
+ searchProfile := mockClient.EXPECT().
+ Search(gomock.Any()).
+ Return(&ldap.SearchResult{
+ Entries: []*ldap.Entry{
+ {
+ DN: "uid=john,dc=example,dc=com",
+ Attributes: []*ldap.EntryAttribute{
+ {
+ Name: "uid",
+ Values: []string{"john"},
+ },
+ {
+ Name: "mail",
+ Values: []string{},
+ },
+ {
+ Name: "displayName",
+ Values: []string{},
+ },
+ {
+ Name: "memberOf",
+ Values: []string{},
+ },
+ {
+ Name: "locale",
+ Values: []string{"ba12390-n2m3jkn123&!@#!_+"},
+ },
+ },
+ },
+ },
+ }, nil)
+
+ searchGroup := mockClient.EXPECT().Search(gomock.Any()).Return(createSearchResultWithAttributes(), nil)
+
+ gomock.InOrder(dialURL, connBind, searchProfile, searchGroup, connClose)
+
+ details, err := provider.GetDetailsExtended("john")
+ assert.Nil(t, details)
+ assert.EqualError(t, err, "error occurred parsing user details for 'john': failed to parse the locale attribute 'locale' with value 'ba12390-n2m3jkn123&!@#!_+': language: tag is not well-formed")
+}
+
func TestLDAPUserProvider_GetDetails_ShouldReturnOnUserError(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
@@ -1210,6 +1938,135 @@ func TestLDAPUserProvider_GetDetails_ShouldReturnOnUserError(t *testing.T) {
assert.EqualError(t, err, "cannot find user DN of user 'john'. Cause: failed to search")
}
+func TestLDAPUserProvider_GetDetailsExtendedShouldReturnOnBindError(t *testing.T) {
+ ctrl := gomock.NewController(t)
+ defer ctrl.Finish()
+
+ mockFactory := NewMockLDAPClientFactory(ctrl)
+ mockClient := NewMockLDAPClient(ctrl)
+
+ provider := NewLDAPUserProviderWithFactory(
+ schema.AuthenticationBackendLDAP{
+ Address: testLDAPAddress,
+ User: "cn=admin,dc=example,dc=com",
+ Password: "password",
+ Attributes: schema.AuthenticationBackendLDAPAttributes{
+ Username: "uid",
+ Mail: "mail",
+ DisplayName: "displayName",
+ MemberOf: "memberOf",
+ },
+ UsersFilter: "uid={input}",
+ AdditionalUsersDN: "ou=users",
+ BaseDN: "dc=example,dc=com",
+ PermitReferrals: true,
+ },
+ false,
+ nil,
+ mockFactory)
+
+ dialURL := mockFactory.EXPECT().
+ DialURL(gomock.Eq("ldap://127.0.0.1:389"), gomock.Any()).
+ Return(mockClient, nil)
+
+ connBind := mockClient.EXPECT().
+ Bind(gomock.Eq("cn=admin,dc=example,dc=com"), gomock.Eq("password")).
+ Return(fmt.Errorf("bad bind"))
+
+ connClose := mockClient.EXPECT().Close().Return(nil)
+
+ gomock.InOrder(dialURL, connBind, connClose)
+
+ details, err := provider.GetDetailsExtended("john")
+ assert.Nil(t, details)
+ assert.EqualError(t, err, "bind failed with error: bad bind")
+}
+
+func TestLDAPUserProvider_GetDetailsExtendedShouldReturnOnDialError(t *testing.T) {
+ ctrl := gomock.NewController(t)
+ defer ctrl.Finish()
+
+ mockFactory := NewMockLDAPClientFactory(ctrl)
+
+ provider := NewLDAPUserProviderWithFactory(
+ schema.AuthenticationBackendLDAP{
+ Address: testLDAPAddress,
+ User: "cn=admin,dc=example,dc=com",
+ Password: "password",
+ Attributes: schema.AuthenticationBackendLDAPAttributes{
+ Username: "uid",
+ Mail: "mail",
+ DisplayName: "displayName",
+ MemberOf: "memberOf",
+ },
+ UsersFilter: "uid={input}",
+ AdditionalUsersDN: "ou=users",
+ BaseDN: "dc=example,dc=com",
+ PermitReferrals: true,
+ },
+ false,
+ nil,
+ mockFactory)
+
+ dialURL := mockFactory.EXPECT().
+ DialURL(gomock.Eq("ldap://127.0.0.1:389"), gomock.Any()).
+ Return(nil, fmt.Errorf("failed to dial"))
+
+ gomock.InOrder(dialURL)
+
+ details, err := provider.GetDetailsExtended("john")
+ assert.Nil(t, details)
+ assert.EqualError(t, err, "dial failed with error: failed to dial")
+}
+
+func TestLDAPUserProvider_GetDetailsExtendedShouldReturnOnUserError(t *testing.T) {
+ ctrl := gomock.NewController(t)
+ defer ctrl.Finish()
+
+ mockFactory := NewMockLDAPClientFactory(ctrl)
+ mockClient := NewMockLDAPClient(ctrl)
+
+ provider := NewLDAPUserProviderWithFactory(
+ schema.AuthenticationBackendLDAP{
+ Address: testLDAPAddress,
+ User: "cn=admin,dc=example,dc=com",
+ Password: "password",
+ Attributes: schema.AuthenticationBackendLDAPAttributes{
+ Username: "uid",
+ Mail: "mail",
+ DisplayName: "displayName",
+ MemberOf: "memberOf",
+ },
+ UsersFilter: "uid={input}",
+ AdditionalUsersDN: "ou=users",
+ BaseDN: "dc=example,dc=com",
+ PermitReferrals: true,
+ },
+ false,
+ nil,
+ mockFactory)
+
+ dialURL := mockFactory.EXPECT().
+ DialURL(gomock.Eq("ldap://127.0.0.1:389"), gomock.Any()).
+ Return(mockClient, nil)
+
+ connBind := mockClient.EXPECT().
+ Bind(gomock.Eq("cn=admin,dc=example,dc=com"), gomock.Eq("password")).
+ Return(nil)
+
+ connClose := mockClient.EXPECT().Close()
+
+ searchProfile := mockClient.EXPECT().
+ Search(gomock.Any()).
+ Return(nil, fmt.Errorf("failed to search"))
+
+ gomock.InOrder(dialURL, connBind, searchProfile, connClose)
+
+ details, err := provider.GetDetailsExtended("john")
+ assert.Nil(t, details)
+ assert.EqualError(t, err, "cannot find user DN of user 'john'. Cause: failed to search")
+}
+
func TestLDAPUserProvider_GetDetails_ShouldReturnOnGroupsError(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()