diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c6ea84bd8..10248be607 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,11 @@ Canonical reference for changes, improvements, and bugfixes for Boundary. the cluster's listener configuration. ([PR](https://github.com/hashicorp/boundary/pull/4803) and [PR](https://github.com/hashicorp/boundary/pull/4805)) +* LDAP account attribute maps. Account attribute maps have been supported since + the introduction of LDAP authentication, however a bug was present where we + wouldn't take those into account upon authenticating (when receiving the + information from the LDAP server). This is now resolved + ([PR]((https://github.com/hashicorp/boundary/pull/4788))). ## 0.16.0 (2024/04/30) diff --git a/internal/auth/ldap/repository_authenticate.go b/internal/auth/ldap/repository_authenticate.go index b289006ec4..0e758391c5 100644 --- a/internal/auth/ldap/repository_authenticate.go +++ b/internal/auth/ldap/repository_authenticate.go @@ -112,15 +112,23 @@ func (r *Repository) Authenticate(ctx context.Context, authMethodId, loginName, fullNameAttr := DefaultFullNameAttribute attrMaps, err := am.convertAccountAttributeMaps(ctx) - if err == nil { - for _, attrMap := range attrMaps { - aam := attrMap.(*AccountAttributeMap) - if aam.ToAttribute == DefaultEmailAttribute { - emailAttr = aam.FromAttribute - } - if aam.ToAttribute == DefaultFullNameAttribute { - fullNameAttr = aam.FromAttribute - } + if err != nil { + return nil, errors.Wrap(ctx, err, op, errors.WithMsg("failed to convert account attribute maps")) + } + + for _, attrMap := range attrMaps { + aam, ok := attrMap.(*AccountAttributeMap) + if !ok { + return nil, errors.New(ctx, errors.Internal, op, "failed to convert attribute map into AccountAttributeMap type") + } + + switch aam.ToAttribute { + case DefaultEmailAttribute: + emailAttr = aam.FromAttribute + case DefaultFullNameAttribute: + fullNameAttr = aam.FromAttribute + default: + return nil, errors.New(ctx, errors.InvalidParameter, op, fmt.Sprintf("invalid to attribute %q", aam.ToAttribute)) } } diff --git a/internal/auth/ldap/repository_authenticate_test.go b/internal/auth/ldap/repository_authenticate_test.go index f28728e5f6..b701c80044 100644 --- a/internal/auth/ldap/repository_authenticate_test.go +++ b/internal/auth/ldap/repository_authenticate_test.go @@ -5,10 +5,12 @@ package ldap import ( "context" + "database/sql/driver" "encoding/pem" "fmt" "testing" + "github.com/DATA-DOG/go-sqlmock" "github.com/google/go-cmp/cmp" "github.com/hashicorp/boundary/internal/auth/ldap/store" "github.com/hashicorp/boundary/internal/db" @@ -250,6 +252,101 @@ func TestRepository_authenticate(t *testing.T) { wantErrMatch: errors.T(errors.Unknown), wantErrContains: "auth-method-id-lookup-err", }, + { + name: "invalid-attribute-maps", + ctx: testCtx, + repo: func() *Repository { + conn, mock := db.TestSetupWithMock(t) + mock.ExpectQuery("SELECT").WillReturnRows(sqlmock.NewRows( + []string{ + "is_primary_auth_method", + "public_id", + "scope_id", + "name", + "description", + "create_time", + "update_time", + "version", + "state", + "start_tls", + "insecure_tls", + "discover_dn", + "anon_group_search", + "upn_domain", + "enable_groups", + "use_token_groups", + "maximum_page_size", + "urls", + "certs", + "account_attribute_map", + "user_dn", + "user_attr", + "user_filter", + "group_dn", + "group_attr", + "group_filter", + "client_certificate_key", + "client_certificate_key_hmac", + "client_certificate_key_id", + "client_certificate_cert", + "bind_dn", + "bind_password", + "bind_password_hmac", + "bind_password_key_id", + "dereference_aliases", + }, + ).AddRow( + "f", + "amldap_badattrs", + "o_1234567890", + nil, + nil, + "2024-05-15 17:40:31.327736+00", + "2024-05-15 17:40:31.327736+00", + 1, + "inactive", + "f", + "f", + "t", + "f", + nil, + "t", + "f", + 0, + fmt.Sprintf("ldaps://%s:%d", td.Host(), td.Port()), + func() driver.Value { + certs, err := EncodeCertificates(testCtx, tdCerts...) + require.NoError(t, err) + return certs[0] + }(), + "at=email|fn=fullName|bad=invalidAttribute", + "ou=people,dc=example,dc=org", + nil, + nil, + "ou=groups,dc=example,dc=org", + nil, + nil, + nil, + nil, + nil, + nil, + nil, + nil, + nil, + nil, + nil, + )) + rw := db.New(conn) + r, err := NewRepository(testCtx, rw, rw, testKms) + require.NoError(t, err) + return r + }(), + authMethodId: "amldap_badattrs", + loginName: "alice", + password: testPassword, + wantErrMatch: errors.T(errors.InvalidParameter), + wantErrContains: `failed to convert account attribute maps: ldap.(AuthMethod).convertAccountAttributeMaps: ldap.ParseAccountAttributeMaps: ldap.ConvertToAccountToAttribute: "invalidAttribute" is not a valid ToAccountAttribute value ("email", "fullName")`, + }, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) {