From 352400eeb6d6a21d6da43c54796d5e5075ced35e Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Mon, 10 Jun 2024 14:34:50 +0100 Subject: [PATCH 1/3] azuread_application: support `ignore_changes` lifecycle argument for `app_role`, `oauth2_permission_scope`, `identifier_uris`, `optional_claims`, and `required_resource_access` --- .../applications/application_resource.go | 45 +++++++++++++------ 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/internal/services/applications/application_resource.go b/internal/services/applications/application_resource.go index 166093d88..73115334f 100644 --- a/internal/services/applications/application_resource.go +++ b/internal/services/applications/application_resource.go @@ -1175,7 +1175,6 @@ func applicationResourceUpdate(ctx context.Context, d *pluginsdk.ResourceData, m var imageContentType string var imageData []byte if v, ok := d.GetOk("logo_image"); ok && v != "" && d.HasChange("logo_image") { - var err error imageContentType, imageData, err = applicationParseLogoImage(v.(string)) if err != nil { return tf.ErrorDiagPathF(err, "image", "Could not decode image data") @@ -1193,12 +1192,9 @@ func applicationResourceUpdate(ctx context.Context, d *pluginsdk.ResourceData, m DirectoryObject: msgraph.DirectoryObject{ Id: pointer.To(id.ApplicationId), }, - Api: expandApplicationApi(d.Get("api").([]interface{})), - AppRoles: expandApplicationAppRoles(d.Get("app_role").(*pluginsdk.Set).List()), Description: tf.NullableString(d.Get("description").(string)), DisplayName: pointer.To(displayName), GroupMembershipClaims: expandApplicationGroupMembershipClaims(d.Get("group_membership_claims").(*pluginsdk.Set).List()), - IdentifierUris: tf.ExpandStringSlicePtr(d.Get("identifier_uris").(*pluginsdk.Set).List()), Info: &msgraph.InformationalUrl{ MarketingUrl: tf.NullableString(d.Get("marketing_url").(string)), PrivacyStatementUrl: tf.NullableString(d.Get("privacy_statement_url").(string)), @@ -1209,9 +1205,7 @@ func applicationResourceUpdate(ctx context.Context, d *pluginsdk.ResourceData, m IsFallbackPublicClient: pointer.To(d.Get("fallback_public_client_enabled").(bool)), Notes: tf.NullableString(d.Get("notes").(string)), Oauth2RequirePostResponse: pointer.To(d.Get("oauth2_post_response_required").(bool)), - OptionalClaims: expandApplicationOptionalClaims(d.Get("optional_claims").([]interface{})), PublicClient: expandApplicationPublicClient(d.Get("public_client").([]interface{})), - RequiredResourceAccess: expandApplicationRequiredResourceAccess(d.Get("required_resource_access").(*pluginsdk.Set).List()), ServiceManagementReference: tf.NullableString(d.Get("service_management_reference").(string)), SignInAudience: pointer.To(d.Get("sign_in_audience").(string)), Spa: expandApplicationSpa(d.Get("single_page_application").([]interface{})), @@ -1219,15 +1213,39 @@ func applicationResourceUpdate(ctx context.Context, d *pluginsdk.ResourceData, m Web: expandApplicationWeb(d.Get("web").([]interface{})), } - if err := applicationDisableAppRoles(ctx, client, &properties, expandApplicationAppRoles(d.Get("app_role").(*pluginsdk.Set).List())); err != nil { - return tf.ErrorDiagPathF(err, "app_role", "Could not disable App Roles for application with object ID %q", id.ApplicationId) + api := expandApplicationApi(d.Get("api").([]interface{})) + + if d.HasChange("app_role") { + if err = applicationDisableAppRoles(ctx, client, &properties, expandApplicationAppRoles(d.Get("app_role").(*pluginsdk.Set).List())); err != nil { + return tf.ErrorDiagPathF(err, "app_role", "Could not disable App Roles for application with object ID %q", id.ApplicationId) + } + + properties.AppRoles = expandApplicationAppRoles(d.Get("app_role").(*pluginsdk.Set).List()) + } + + if d.HasChange("api.0.oauth2_permission_scope") { + if err = applicationDisableOauth2PermissionScopes(ctx, client, &properties, expandApplicationOAuth2PermissionScope(d.Get("api.0.oauth2_permission_scope").(*pluginsdk.Set).List())); err != nil { + return tf.ErrorDiagPathF(err, "api.0.oauth2_permission_scope", "Could not disable OAuth2 Permission Scopes for application with object ID %q", id.ApplicationId) + } + } else { + api.OAuth2PermissionScopes = nil + } + + if d.HasChange("identifier_uris") { + properties.IdentifierUris = tf.ExpandStringSlicePtr(d.Get("identifier_uris").(*pluginsdk.Set).List()) } - if err := applicationDisableOauth2PermissionScopes(ctx, client, &properties, expandApplicationOAuth2PermissionScope(d.Get("api.0.oauth2_permission_scope").(*pluginsdk.Set).List())); err != nil { - return tf.ErrorDiagPathF(err, "api.0.oauth2_permission_scope", "Could not disable OAuth2 Permission Scopes for application with object ID %q", id.ApplicationId) + if d.HasChange("optional_claims") { + properties.OptionalClaims = expandApplicationOptionalClaims(d.Get("optional_claims").([]interface{})) } - if _, err := client.Update(ctx, properties); err != nil { + if d.HasChange("required_resource_access") { + properties.RequiredResourceAccess = expandApplicationRequiredResourceAccess(d.Get("required_resource_access").(*pluginsdk.Set).List()) + } + + properties.Api = api + + if _, err = client.Update(ctx, properties); err != nil { return tf.ErrorDiagF(err, "Could not update application with object ID: %q", id.ApplicationId) } @@ -1253,7 +1271,7 @@ func applicationResourceUpdate(ctx context.Context, d *pluginsdk.ResourceData, m } properties.Owners = &newOwners - if _, err := client.AddOwners(ctx, &properties); err != nil { + if _, err = client.AddOwners(ctx, &properties); err != nil { return tf.ErrorDiagF(err, "Could not add owners to application with object ID: %q", id.ApplicationId) } } @@ -1267,8 +1285,7 @@ func applicationResourceUpdate(ctx context.Context, d *pluginsdk.ResourceData, m // Upload the application image if imageContentType != "" && len(imageData) > 0 { - _, err := client.UploadLogo(ctx, id.ApplicationId, imageContentType, imageData) - if err != nil { + if _, err = client.UploadLogo(ctx, id.ApplicationId, imageContentType, imageData); err != nil { return tf.ErrorDiagF(err, "Could not upload logo image for application with object ID: %q", id.ApplicationId) } } From 9ccbe4829c37ef7e131234c17761a897feef0f66 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Mon, 10 Jun 2024 14:59:25 +0100 Subject: [PATCH 2/3] azuread_application: basicFromTemplate test fix --- .../applications/application_resource_test.go | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/internal/services/applications/application_resource_test.go b/internal/services/applications/application_resource_test.go index 3e8b9b21a..7b2cee05e 100644 --- a/internal/services/applications/application_resource_test.go +++ b/internal/services/applications/application_resource_test.go @@ -635,8 +635,21 @@ resource "azuread_application" "test" { display_name = "acctest-APP-%[1]d" owners = [data.azuread_client_config.test.object_id] template_id = "%[2]s" + + api { + oauth2_permission_scope { + admin_consent_description = "Allow the application to access acctest-APP-%[1]d on behalf of the signed-in user." + admin_consent_display_name = "Access acctest-APP-%[1]d" + enabled = true + id = "%[3]s" + type = "User" + user_consent_description = "Allow the application to access acctest-APP-%[1]d on your behalf." + user_consent_display_name = "Access acctest-APP-%[1]d" + value = "user_impersonation" + } + } } -`, data.RandomInteger, testApplicationTemplateId) +`, data.RandomInteger, testApplicationTemplateId, data.UUID()) } func (ApplicationResource) withGroupMembershipClaims(data acceptance.TestData) string { From bca227c2b094e25bb7af1174ee184a7870247bf1 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Mon, 10 Jun 2024 15:53:45 +0100 Subject: [PATCH 3/3] azuread_application: basicFromTemplate more test fix --- .../services/applications/application_resource_test.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/internal/services/applications/application_resource_test.go b/internal/services/applications/application_resource_test.go index 7b2cee05e..2c20290ae 100644 --- a/internal/services/applications/application_resource_test.go +++ b/internal/services/applications/application_resource_test.go @@ -648,6 +648,16 @@ resource "azuread_application" "test" { value = "user_impersonation" } } + + app_role { + allowed_member_types = [ + "User", + ] + description = "msiam_access" + display_name = "msiam_access" + enabled = true + id = "dfd0e7dd-26fb-4b2c-98d2-e444486c1e37" + } } `, data.RandomInteger, testApplicationTemplateId, data.UUID()) }