fix (ldap): support only updating the bind-dn and/or bind-password (#3511)

* fix (ldap): support only updating the bind-dn and/or bind-password

* chore: changelog entry for PR #3511
This commit is contained in:
Jim authored and GitHub committed 2023-07-27 15:41:37 -04:00
1 parent da7e8f7c1c
commit f8ea8c9744
9 files changed
+211 -41

No files matched your search

@@ -1232,8 +1232,7 @@ func TestCreate(t *testing.T) {
},
},
}},
err: handlers.ApiErrorWithCode(codes.InvalidArgument),
errContains: "attributes.bind_password is missing required attributes.bind_dn field",
errContains: "missing dn",
},
{
name: "ldap-auth-method-missing-bind-password",
@@ -1247,8 +1246,7 @@ func TestCreate(t *testing.T) {
},
},
}},
err: handlers.ApiErrorWithCode(codes.InvalidArgument),
errContains: "attributes.bind_dn is missing required attributes.bind_password field",
errContains: "missing password",
},
{
name: "ldap-auth-method-invalid-client-cert",
@@ -1352,14 +1350,20 @@ func TestCreate(t *testing.T) {
require.NoError(err, "Error when getting new auth_method service.")
got, gErr := s.CreateAuthMethod(requestauth.DisabledAuthTestContext(iamRepoFn, tc.req.GetItem().GetScopeId()), tc.req)
if tc.err != nil {
switch {
case tc.err != nil:
require.Error(gErr)
assert.True(errors.Is(gErr, tc.err), "CreateAuthMethod(%+v) got error %v, wanted %v", tc.req, gErr, tc.err)
if tc.errContains != "" {
assert.Contains(gErr.Error(), tc.errContains)
}
return
case tc.errContains != "":
require.Error(gErr)
assert.Contains(gErr.Error(), tc.errContains)
return
}
require.NoError(gErr)
if tc.res == nil {
require.Nil(got)
@@ -299,12 +299,6 @@ func validateLdapAttributes(ctx context.Context, attrs *pb.LdapAuthMethodAttribu
badFields[certificatesField] = fmt.Sprintf("invalid %s: %s", certificatesField, err.Error())
}
}
if attrs.GetBindDn().GetValue() != "" && attrs.GetBindPassword().GetValue() == "" {
badFields[bindPasswordField] = fmt.Sprintf("%s is missing required %s field", bindDnField, bindPasswordField)
}
if attrs.GetBindPassword().GetValue() != "" && attrs.GetBindDn().GetValue() == "" {
badFields[bindDnField] = fmt.Sprintf("%s is missing required %s field", bindPasswordField, bindDnField)
}
if attrs.GetClientCertificate().GetValue() != "" && attrs.GetClientCertificateKey().GetValue() == "" {
badFields[clientCertificateKeyField] = fmt.Sprintf("%s is missing required %s field", clientCertificateField, clientCertificateKeyField)
}
@@ -81,14 +81,17 @@ func Test_UpdateLdap(t *testing.T) {
},
}
freshAuthMethod := func(t *testing.T) (*pb.AuthMethod, func()) {
freshAuthMethod := func(t *testing.T, attrs *pb.AuthMethod_LdapAuthMethodsAttributes) (*pb.AuthMethod, func()) {
if attrs == nil {
attrs = defaultAttributes
}
ctx := auth.DisabledAuthTestContext(iamRepoFn, o.GetPublicId())
am, err := tested.CreateAuthMethod(ctx, &pbs.CreateAuthMethodRequest{Item: &pb.AuthMethod{
ScopeId: o.GetPublicId(),
Name: wrapperspb.String("default"),
Description: wrapperspb.String("default"),
Type: ldap.Subtype.String(),
Attrs: defaultAttributes,
Attrs: attrs,
}})
require.NoError(t, err)
@@ -103,12 +106,13 @@ func Test_UpdateLdap(t *testing.T) {
_, testEncodedCert := ldap.TestGenerateCA(t, "localhost")
tests := []struct {
name string
req *pbs.UpdateAuthMethodRequest
res *pbs.UpdateAuthMethodResponse
err error
errContains string
wantErr bool
name string
newAttrsOverride *pb.AuthMethod_LdapAuthMethodsAttributes
req *pbs.UpdateAuthMethodRequest
res *pbs.UpdateAuthMethodResponse
err error
errContains string
wantErr bool
}{
{
name: "update-an-existing-auth-method",
@@ -349,6 +353,128 @@ func Test_UpdateLdap(t *testing.T) {
},
},
},
{
name: "update-only-bind-dn",
newAttrsOverride: &pb.AuthMethod_LdapAuthMethodsAttributes{
LdapAuthMethodsAttributes: &pb.LdapAuthMethodAttributes{
Urls: []string{"ldaps://ldap1"},
State: "active-private",
BindDn: &wrapperspb.StringValue{Value: "bind-dn"},
BindPassword: &wrapperspb.StringValue{Value: "bind-password"},
},
},
req: &pbs.UpdateAuthMethodRequest{
UpdateMask: &field_mask.FieldMask{
Paths: []string{"attributes.bind_dn"},
},
Item: &pb.AuthMethod{
Attrs: &pb.AuthMethod_LdapAuthMethodsAttributes{
LdapAuthMethodsAttributes: &pb.LdapAuthMethodAttributes{
BindDn: &wrapperspb.StringValue{Value: "updated"},
},
},
},
},
res: &pbs.UpdateAuthMethodResponse{
Item: &pb.AuthMethod{
ScopeId: o.GetPublicId(),
Version: 2,
Name: &wrapperspb.StringValue{Value: "default"},
Description: &wrapperspb.StringValue{Value: "default"},
Type: ldap.Subtype.String(),
Attrs: &pb.AuthMethod_LdapAuthMethodsAttributes{
LdapAuthMethodsAttributes: &pb.LdapAuthMethodAttributes{
Urls: []string{"ldaps://ldap1"},
State: "active-private",
BindDn: &wrapperspb.StringValue{Value: "updated"},
// note: BindPassword is never returned (an HMAC'd
// value is returned in a separate attribute)
},
},
Scope: defaultScopeInfo,
AuthorizedActions: ldapAuthorizedActions,
AuthorizedCollectionActions: authorizedCollectionActions,
},
},
},
{
name: "err-update-only-bind-dn-with-no-orig-bind-password",
req: &pbs.UpdateAuthMethodRequest{
UpdateMask: &field_mask.FieldMask{
Paths: []string{"attributes.bind_dn"},
},
Item: &pb.AuthMethod{
Attrs: &pb.AuthMethod_LdapAuthMethodsAttributes{
LdapAuthMethodsAttributes: &pb.LdapAuthMethodAttributes{
BindDn: &wrapperspb.StringValue{Value: "updated"},
},
},
},
},
err: handlers.ApiErrorWithCode(codes.InvalidArgument),
errContains: "missing password",
},
{
name: "update-only-bind-password",
newAttrsOverride: &pb.AuthMethod_LdapAuthMethodsAttributes{
LdapAuthMethodsAttributes: &pb.LdapAuthMethodAttributes{
Urls: []string{"ldaps://ldap1"},
State: "active-private",
BindDn: &wrapperspb.StringValue{Value: "bind-dn"},
BindPassword: &wrapperspb.StringValue{Value: "bind-password"},
},
},
req: &pbs.UpdateAuthMethodRequest{
UpdateMask: &field_mask.FieldMask{
Paths: []string{"attributes.bind_password"},
},
Item: &pb.AuthMethod{
Attrs: &pb.AuthMethod_LdapAuthMethodsAttributes{
LdapAuthMethodsAttributes: &pb.LdapAuthMethodAttributes{
BindPassword: &wrapperspb.StringValue{Value: "updated"},
},
},
},
},
res: &pbs.UpdateAuthMethodResponse{
Item: &pb.AuthMethod{
ScopeId: o.GetPublicId(),
Version: 2,
Name: &wrapperspb.StringValue{Value: "default"},
Description: &wrapperspb.StringValue{Value: "default"},
Type: ldap.Subtype.String(),
Attrs: &pb.AuthMethod_LdapAuthMethodsAttributes{
LdapAuthMethodsAttributes: &pb.LdapAuthMethodAttributes{
Urls: []string{"ldaps://ldap1"},
State: "active-private",
BindDn: &wrapperspb.StringValue{Value: "bind-dn"},
// note: BindPassword is never returned (an HMAC'd
// value is returned in a separate attribute)
},
},
Scope: defaultScopeInfo,
AuthorizedActions: ldapAuthorizedActions,
AuthorizedCollectionActions: authorizedCollectionActions,
},
},
},
{
name: "err-update-only-bind-password-with-no-orig-bind-dn",
req: &pbs.UpdateAuthMethodRequest{
UpdateMask: &field_mask.FieldMask{
Paths: []string{"attributes.bind_password"},
},
Item: &pb.AuthMethod{
Attrs: &pb.AuthMethod_LdapAuthMethodsAttributes{
LdapAuthMethodsAttributes: &pb.LdapAuthMethodAttributes{
BindPassword: &wrapperspb.StringValue{Value: "updated"},
},
},
},
},
err: handlers.ApiErrorWithCode(codes.InvalidArgument),
errContains: "missing dn",
},
{
name: "update-a-non-existent-auth-method",
req: &pbs.UpdateAuthMethodRequest{
@@ -689,7 +815,7 @@ func Test_UpdateLdap(t *testing.T) {
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
am, cleanup := freshAuthMethod(t)
am, cleanup := freshAuthMethod(t, tc.newAttrsOverride)
defer cleanup()
tc.req.Item.Version = am.GetVersion()