diff --git a/provider/common/attrvalidators/list.go b/provider/common/attrvalidators/list.go index 138a9955..0ff0e370 100644 --- a/provider/common/attrvalidators/list.go +++ b/provider/common/attrvalidators/list.go @@ -26,5 +26,4 @@ func NewListValidator(desc string, validator func(ctx context.Context, req valid desc: desc, validator: validator, } - } diff --git a/provider/identityprovider/htpasswd.go b/provider/identityprovider/htpasswd.go index 8bdb0119..5483ac46 100644 --- a/provider/identityprovider/htpasswd.go +++ b/provider/identityprovider/htpasswd.go @@ -2,6 +2,7 @@ package identityprovider import ( "context" + "fmt" "regexp" "github.com/hashicorp/terraform-plugin-framework-validators/listvalidator" @@ -9,6 +10,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/terraform-redhat/terraform-provider-rhcs/provider/common/attrvalidators" cmv1 "github.com/openshift-online/ocm-sdk-go/clustersmgmt/v1" ) @@ -53,6 +55,7 @@ var htpasswdSchema = map[string]schema.Attribute{ }, Validators: []validator.List{ listvalidator.SizeAtLeast(1), + uniqueUsernameValidator(), }, Required: true, }, @@ -86,3 +89,24 @@ func CreateHTPasswdIDPBuilder(ctx context.Context, state *HTPasswdIdentityProvid builder.Users(userListBuilder) return builder } + +func uniqueUsernameValidator() validator.List { + return attrvalidators.NewListValidator("userlist unique username", func(ctx context.Context, req validator.ListRequest, resp *validator.ListResponse) { + usersList := req.ConfigValue + htusers := []HTPasswdUser{} + err := usersList.ElementsAs(ctx, &htusers, true) + if err != nil { + resp.Diagnostics.AddAttributeError(req.Path, "Invalid list conversion", "Failed to parse userlist") + return + } + usernames := make(map[string]bool) + for _, user := range htusers { + if _, ok := usernames[user.Username.ValueString()]; ok { + // Username already exists + resp.Diagnostics.AddAttributeError(req.Path, fmt.Sprintf("Found duplicate username: '%s'", user.Username.ValueString()), "Usernames in HTPasswd user list must be unique") + return + } + usernames[user.Username.ValueString()] = true + } + }) +} diff --git a/subsystem/identity_provider_resource_test.go b/subsystem/identity_provider_resource_test.go index 5ffa7765..f76e7e81 100644 --- a/subsystem/identity_provider_resource_test.go +++ b/subsystem/identity_provider_resource_test.go @@ -94,6 +94,28 @@ var _ = Describe("Identity provider creation", func() { users = [] } } + `) + Expect(terraform.Apply()).ToNot(BeZero()) + }) + It("Can't create a 'htpasswd' identity provider. duplication of username", func() { + // Run the apply command: + terraform.Source(` + resource "rhcs_identity_provider" "my_ip" { + cluster = "123" + name = "my-ip" + htpasswd = { + users = [ + { + username = "foo" + password = "` + htpasswdValidPass + `" + }, + { + username = "foo" + password = "` + htpasswdValidPass + `" + } + ] + } + } `) Expect(terraform.Apply()).ToNot(BeZero()) })