Skip to content

Commit

Permalink
Bugfix: enable specifying metadata for app and SP passwords
Browse files Browse the repository at this point in the history
- Can now set display_name, start_date, end_date and end_date_relative
- Update Hamilton for this, and another fix to mitigate access token refresh race
  • Loading branch information
manicminer authored and romainDavaze committed Jul 5, 2021
1 parent c16e176 commit b0244ec
Show file tree
Hide file tree
Showing 17 changed files with 537 additions and 152 deletions.
12 changes: 0 additions & 12 deletions docs/guides/microsoft-graph.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,14 +180,8 @@ The deprecated field `description` has been replaced by the `display_name` field

-> The following also applies when the Microsoft Graph beta is enabled in version 1.5 or later

The `display_name` field will become read-only as Azure Active Directory no longer respects user-supplied display names for passwords.

The `key_id` field will become read-only as Azure Active Directory no longer allows user-specified key IDs for passwords. This also means that the `azuread_application_password` resource no longer supports importing in version 2.0 of the provider.

The `start_date` field will become read-only as Azure Active Directory no longer respects user-supplied start dates for passwords. Passwords will be valid immediately on creation.

The `end_date` and `end_date_relative` fields will become read-only as Azure Active Directory no longer respects user-supplied end dates for passwords. Passwords will be valid for a period of 2 years, or whatever period is automatically deemed when creating the password.

The `value` field will become read-only as Azure Active Directory no longer accepts user-supplied password values. Passwords will instead be auto-generated by Azure and will be exported as attributes by the resource.

### Resource: `azuread_group`
Expand All @@ -200,14 +194,8 @@ The deprecated field `description` has been replaced by the `display_name` field

-> The following also applies when the Microsoft Graph beta is enabled in version 1.5 or later

The `display_name` field will become read-only as Azure Active Directory no longer respects user-supplied display names for passwords.

The `key_id` field will become read-only as Azure Active Directory no longer allows user-specified key IDs for passwords. This also means that the `azuread_service_principal_password` resource no longer supports importing in version 2.0 of the provider.

The `start_date` field will become read-only as Azure Active Directory no longer respects user-supplied start dates for passwords. Passwords will be valid immediately on creation.

The `end_date` and `end_date_relative` fields will become read-only as Azure Active Directory no longer respects user-supplied end dates for passwords. Passwords will be valid for a period of 2 years, or whatever period is automatically deemed when creating the password.

The `value` field will become read-only as Azure Active Directory no longer accepts user-supplied password values. Passwords will instead be auto-generated by Azure and will be exported as attributes by the resource.

### Resource: `azuread_user`
Expand Down
2 changes: 1 addition & 1 deletion docs/resources/application_password.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ resource "azuread_application_password" "example" {

## Argument Reference

~> **IMPORTANT:** In version 2.0 of the provider, or when using the Microsoft Graph beta in version 1.5 or later, the `key_id`, `display_name` / `description`, `start_date`, `end_date` / `end_date_relative` and `value` properties will all become read-only and should not be specified. For more information, see the [Upgrade Guide for v2.0](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/guides/microsoft-graph#resource-azuread_application_password).
~> **IMPORTANT:** In version 2.0 of the provider, or when using the Microsoft Graph beta in version 1.5 or later, the `key_id` and `value` properties will become read-only and should not be specified. For more information, see the [Upgrade Guide for v2.0](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/guides/microsoft-graph#resource-azuread_application_password).

The following arguments are supported:

Expand Down
2 changes: 1 addition & 1 deletion docs/resources/service_principal_password.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ resource "azuread_service_principal_password" "example" {

## Argument Reference

~> **IMPORTANT:** In version 2.0 of the provider, or when using the Microsoft Graph beta in version 1.5 or later, the `key_id`, `display_name` / `description`, `start_date`, `end_date` / `end_date_relative` and `value` properties will all become read-only and should not be specified. For more information, see the [Upgrade Guide for v2.0](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/guides/microsoft-graph#resource-azuread_service_principal_password).
~> **IMPORTANT:** In version 2.0 of the provider, or when using the Microsoft Graph beta in version 1.5 or later, the `key_id` and `value` properties will become read-only and should not be specified. For more information, see the [Upgrade Guide for v2.0](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/guides/microsoft-graph#resource-azuread_service_principal_password).

The following arguments are supported:

Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ require (
github.com/hashicorp/terraform-plugin-sdk/v2 v2.6.1
github.com/hashicorp/yamux v0.0.0-20210316155119-a95892c5f864 // indirect
github.com/klauspost/compress v1.12.2 // indirect
github.com/manicminer/hamilton v0.13.0
github.com/manicminer/hamilton v0.14.1
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
github.com/mitchellh/mapstructure v1.4.1 // indirect
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -314,8 +314,8 @@ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/manicminer/hamilton v0.13.0 h1:aMYcFgHp/+Ph++1MYUaAxsXtrb9ZlN3Lm/mQpVdhUlc=
github.com/manicminer/hamilton v0.13.0/go.mod h1:j/n0It21FsOl/7JJQiJspQT1jw/gpcbnUh/A194j3HU=
github.com/manicminer/hamilton v0.14.1 h1:VbervWkDvX42MifF5gr0qPUPOyWXu3ih3oXt5FvqM6E=
github.com/manicminer/hamilton v0.14.1/go.mod h1:j/n0It21FsOl/7JJQiJspQT1jw/gpcbnUh/A194j3HU=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,30 +22,10 @@ func applicationPasswordResourceCreateMsGraph(ctx context.Context, d *schema.Res
client := meta.(*clients.Client).Applications.MsClient
objectId := d.Get("application_object_id").(string)

if val, ok := d.GetOk("description"); ok && val.(string) != "" {
return tf.ErrorDiagPathF(fmt.Errorf("`description` is a read-only field when using Microsoft Graph. Please remove the `description` field from your configuration"), "description", "Creating application password")
}

if val, ok := d.GetOk("display_name"); ok && val.(string) != "" {
return tf.ErrorDiagPathF(fmt.Errorf("`display_name` is a read-only field when using Microsoft Graph. Please remove the `display_name` field from your configuration"), "display_name", "Creating application password")
}

if val, ok := d.GetOk("end_date"); ok && val.(string) != "" {
return tf.ErrorDiagPathF(fmt.Errorf("`end_date` is a read-only field when using Microsoft Graph. Please remove the `end_date` field from your configuration"), "end_date", "Creating application password")
}

if val, ok := d.GetOk("end_date_relative"); ok && val.(string) != "" {
return tf.ErrorDiagPathF(fmt.Errorf("`end_date_relative` is a read-only field when using Microsoft Graph. Please remove the `end_date_relative` field from your configuration"), "end_date_relative", "Creating application password")
}

if val, ok := d.GetOk("key_id"); ok && val.(string) != "" {
return tf.ErrorDiagPathF(fmt.Errorf("`key_id` is a read-only field when using Microsoft Graph. Please remove the `key_id` field from your configuration"), "key_id", "Creating application password")
}

if val, ok := d.GetOk("start_date"); ok && val.(string) != "" {
return tf.ErrorDiagPathF(fmt.Errorf("`start_date` is a read-only field when using Microsoft Graph. Please remove the `start_date` field from your configuration"), "start_date", "Creating application password")
}

if val, ok := d.GetOk("value"); ok && val.(string) != "" {
return tf.ErrorDiagPathF(fmt.Errorf("`value` is a read-only field when using Microsoft Graph. Please remove the `value` field from your configuration"), "value", "Creating application password")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,45 @@ func TestAccApplicationPassword_basic(t *testing.T) {
})
}

func TestAccApplicationPassword_complete(t *testing.T) {
data := acceptance.BuildTestData(t, "azuread_application_password", "test")
startDate := time.Now().AddDate(0, 0, 7).UTC().Format(time.RFC3339)
endDate := time.Now().AddDate(0, 5, 27).UTC().Format(time.RFC3339)
r := ApplicationPasswordResource{}

data.ResourceTest(t, r, []resource.TestStep{
{
Config: r.complete(data, startDate, endDate),
Check: resource.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
check.That(data.ResourceName).Key("end_date").Exists(),
check.That(data.ResourceName).Key("key_id").Exists(),
check.That(data.ResourceName).Key("start_date").Exists(),
check.That(data.ResourceName).Key("value").Exists(),
),
},
})
}

func TestAccApplicationPassword_relativeEndDate(t *testing.T) {
data := acceptance.BuildTestData(t, "azuread_application_password", "test")
r := ApplicationPasswordResource{}

data.ResourceTest(t, r, []resource.TestStep{
{
Config: r.relativeEndDate(data),
Check: resource.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
check.That(data.ResourceName).Key("end_date").Exists(),
check.That(data.ResourceName).Key("end_date_relative").HasValue("8760h"),
check.That(data.ResourceName).Key("key_id").Exists(),
check.That(data.ResourceName).Key("start_date").Exists(),
check.That(data.ResourceName).Key("value").Exists(),
),
},
})
}

func TestAccApplicationPassword_updateDeprecated(t *testing.T) {
// TODO: remove this test in v2.0
if v := os.Getenv("AAD_USE_MICROSOFT_GRAPH"); v != "" {
Expand Down Expand Up @@ -208,6 +247,31 @@ resource "azuread_application_password" "test" {
`, r.template(data))
}

func (r ApplicationPasswordResource) complete(data acceptance.TestData, startDate, endDate string) string {
return fmt.Sprintf(`
%[1]s
resource "azuread_application_password" "test" {
application_object_id = azuread_application.test.object_id
display_name = "terraform-%[2]s"
start_date = "%[3]s"
end_date = "%[4]s"
}
`, r.template(data), data.RandomString, startDate, endDate)
}

func (r ApplicationPasswordResource) relativeEndDate(data acceptance.TestData) string {
return fmt.Sprintf(`
%[1]s
resource "azuread_application_password" "test" {
application_object_id = azuread_application.test.id
display_name = "terraform-%[2]s"
end_date_relative = "8760h"
}
`, r.template(data), data.RandomString)
}

func (r ApplicationPasswordResource) basicAadGraph(data acceptance.TestData, endDate string) string {
// TODO: remove this config in v2.0
return fmt.Sprintf(`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,30 +22,10 @@ func servicePrincipalPasswordResourceCreateMsGraph(ctx context.Context, d *schem
client := meta.(*clients.Client).ServicePrincipals.MsClient
objectId := d.Get("service_principal_id").(string)

if val, ok := d.GetOk("description"); ok && val.(string) != "" {
return tf.ErrorDiagPathF(fmt.Errorf("`description` is a read-only field when using Microsoft Graph. Please remove the `description` field from your configuration"), "description", "Creating service principal password")
}

if val, ok := d.GetOk("display_name"); ok && val.(string) != "" {
return tf.ErrorDiagPathF(fmt.Errorf("`display_name` is a read-only field when using Microsoft Graph. Please remove the `display_name` field from your configuration"), "display_name", "Creating service principal password")
}

if val, ok := d.GetOk("end_date"); ok && val.(string) != "" {
return tf.ErrorDiagPathF(fmt.Errorf("`end_date` is a read-only field when using Microsoft Graph. Please remove the `end_date` field from your configuration"), "end_date", "Creating service principal password")
}

if val, ok := d.GetOk("end_date_relative"); ok && val.(string) != "" {
return tf.ErrorDiagPathF(fmt.Errorf("`end_date_relative` is a read-only field when using Microsoft Graph. Please remove the `end_date_relative` field from your configuration"), "end_date_relative", "Creating service principal password")
}

if val, ok := d.GetOk("key_id"); ok && val.(string) != "" {
return tf.ErrorDiagPathF(fmt.Errorf("`key_id` is a read-only field when using Microsoft Graph. Please remove the `key_id` field from your configuration"), "key_id", "Creating service principal password")
}

if val, ok := d.GetOk("start_date"); ok && val.(string) != "" {
return tf.ErrorDiagPathF(fmt.Errorf("`start_date` is a read-only field when using Microsoft Graph. Please remove the `start_date` field from your configuration"), "start_date", "Creating service principal password")
}

if val, ok := d.GetOk("value"); ok && val.(string) != "" {
return tf.ErrorDiagPathF(fmt.Errorf("`value` is a read-only field when using Microsoft Graph. Please remove the `value` field from your configuration"), "value", "Creating service principal password")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,45 @@ func TestAccServicePrincipalPassword_basic(t *testing.T) {
})
}

func TestAccServicePrincipalPassword_complete(t *testing.T) {
data := acceptance.BuildTestData(t, "azuread_service_principal_password", "test")
startDate := time.Now().AddDate(0, 0, 7).UTC().Format(time.RFC3339)
endDate := time.Now().AddDate(0, 5, 27).UTC().Format(time.RFC3339)
r := ServicePrincipalPasswordResource{}

data.ResourceTest(t, r, []resource.TestStep{
{
Config: r.complete(data, startDate, endDate),
Check: resource.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
check.That(data.ResourceName).Key("key_id").Exists(),
check.That(data.ResourceName).Key("start_date").Exists(),
check.That(data.ResourceName).Key("end_date").Exists(),
check.That(data.ResourceName).Key("value").Exists(),
),
},
})
}

func TestAccServicePrincipalPassword_relativeEndDate(t *testing.T) {
data := acceptance.BuildTestData(t, "azuread_service_principal_password", "test")
r := ServicePrincipalPasswordResource{}

data.ResourceTest(t, r, []resource.TestStep{
{
Config: r.relativeEndDate(data),
Check: resource.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
check.That(data.ResourceName).Key("key_id").Exists(),
check.That(data.ResourceName).Key("start_date").Exists(),
check.That(data.ResourceName).Key("end_date").Exists(),
check.That(data.ResourceName).Key("end_date_relative").HasValue("8760h"),
check.That(data.ResourceName).Key("value").Exists(),
),
},
})
}

func TestAccServicePrincipalPassword_updateDeprecated(t *testing.T) {
// TODO: remove this test in v2.0
if v := os.Getenv("AAD_USE_MICROSOFT_GRAPH"); v != "" {
Expand Down Expand Up @@ -211,6 +250,31 @@ resource "azuread_service_principal_password" "test" {
`, r.template(data))
}

func (r ServicePrincipalPasswordResource) complete(data acceptance.TestData, startDate, endDate string) string {
return fmt.Sprintf(`
%[1]s
resource "azuread_service_principal_password" "test" {
service_principal_id = azuread_service_principal.test.object_id
display_name = "terraform-%[2]s"
start_date = "%[3]s"
end_date = "%[4]s"
}
`, r.template(data), data.RandomString, startDate, endDate)
}

func (r ServicePrincipalPasswordResource) relativeEndDate(data acceptance.TestData) string {
return fmt.Sprintf(`
%[1]s
resource "azuread_service_principal_password" "test" {
service_principal_id = azuread_service_principal.test.object_id
display_name = "terraform-%[2]s"
end_date_relative = "8760h"
}
`, r.template(data), data.RandomString)
}

func (r ServicePrincipalPasswordResource) basicAadGraph(data acceptance.TestData, endDate string) string {
// TODO: remove this config in v2.0
return fmt.Sprintf(`
Expand Down
9 changes: 7 additions & 2 deletions vendor/github.com/manicminer/hamilton/auth/cache.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit b0244ec

Please sign in to comment.