Skip to content

Commit

Permalink
fix: validate admin user
Browse files Browse the repository at this point in the history
  • Loading branch information
amandahla committed Dec 17, 2024
1 parent e36c04a commit e4f848e
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 5 deletions.
19 changes: 14 additions & 5 deletions internal/provider/resource_access_offer.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,9 @@ func (a *accessOfferResource) Create(ctx context.Context, req resource.CreateReq
}
}

// validate if there are overlaps
// validate if there are overlaps or admin user
// validation is done here considering dynamic (juju_user resource) and static values for users
err := validateNoOverlaps(adminUsers, consumeUsers, readUsers)
err := validateNoOverlapsNoAdmin(adminUsers, consumeUsers, readUsers)
if err != nil {
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to create access offer resource, got error: %s", err))
return
Expand Down Expand Up @@ -307,9 +307,9 @@ func (a *accessOfferResource) Update(ctx context.Context, req resource.UpdateReq
}
}

// validate if there are overlaps
// validate if there are overlaps or admin user
// validation is done here considering dynamic (juju_user resource) and static values for users
err := validateNoOverlaps(adminUsers, consumeUsers, readUsers)
err := validateNoOverlapsNoAdmin(adminUsers, consumeUsers, readUsers)
if err != nil {
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to create access offer resource, got error: %s", err))
return
Expand Down Expand Up @@ -509,18 +509,27 @@ func (a *accessOfferResource) trace(msg string, additionalFields ...map[string]i
}

// Helpers
func validateNoOverlaps(admin, consume, read []string) error {
func validateNoOverlapsNoAdmin(admin, consume, read []string) error {
sets := map[string]struct{}{}
for _, v := range consume {
if v == "admin" {
return fmt.Errorf("user admin is not allowed")
}
sets[v] = struct{}{}
}
for _, v := range read {
if v == "admin" {
return fmt.Errorf("user admin is not allowed")
}
if _, exists := sets[v]; exists {
return fmt.Errorf("user '%s' appears in both 'consume' and 'read'", v)
}
sets[v] = struct{}{}
}
for _, v := range admin {
if v == "admin" {
return fmt.Errorf("user admin is not allowed")
}
if _, exists := sets[v]; exists {
return fmt.Errorf("user '%s' appears in multiple roles (e.g., 'consume', 'read', 'admin')", v)
}
Expand Down
46 changes: 46 additions & 0 deletions internal/provider/resource_access_offer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,23 @@ func TestAcc_ResourceAccessOffer_ErrorWhenUsedWithJAAS(t *testing.T) {
})
}

func TestAcc_ResourceAccessOffer_ErrorWhenUsedWithAdmin(t *testing.T) {
SkipJAAS(t)

modelNameAdminTest := acctest.RandomWithPrefix("tf-access-admin-model")

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProtoV6ProviderFactories: frameworkProviderFactories,
Steps: []resource.TestStep{
{ // Test username admin validation
Config: testAccResourceAccessOfferAdminUser(modelNameAdminTest),
ExpectError: regexp.MustCompile("user admin is not allowed.*"),
},
},
})
}

func testAccResourceAccessOfferFixedUser() string {
return `
resource "juju_access_offer" "test" {
Expand All @@ -92,6 +109,35 @@ resource "juju_access_offer" "test" {
}`
}

func testAccResourceAccessOfferAdminUser(modelName string) string {
return internaltesting.GetStringFromTemplateWithData("testAccResourceAccessOfferAdminUser", `
resource "juju_model" "{{.ModelName}}" {
name = "{{.ModelName}}"
}
resource "juju_application" "appone" {
name = "appone"
model = juju_model.{{.ModelName}}.name
charm {
name = "juju-qa-dummy-source"
base = "[email protected]"
}
}
resource "juju_offer" "appone_endpoint" {
model = juju_model.{{.ModelName}}.name
application_name = juju_application.appone.name
endpoint = "sink"
}
resource "juju_access_offer" "test" {
offer_url = juju_offer.appone_endpoint.url
admin = ["admin"]
}`, internaltesting.TemplateData{
"ModelName": modelName})
}

func testAccResourceAccessOffer(AdminUserName, ConsumeUserName, ReadUserName, OfferAdmin, OfferConsume, OfferRead, userPassword, modelName string) string {
return internaltesting.GetStringFromTemplateWithData(
"testAccResourceAccessOffer",
Expand Down

0 comments on commit e4f848e

Please sign in to comment.