From a7d331dbd74a84548d6a2f5ef14fdbd44319279c Mon Sep 17 00:00:00 2001 From: Jan Schumann Date: Tue, 14 May 2019 15:25:47 +0200 Subject: [PATCH 1/4] implement oauth2_permission attribute --- azuread/data_application.go | 52 +++++++++++++++ azuread/data_application_test.go | 2 + azuread/resource_application.go | 94 ++++++++++++++++++++++++++++ azuread/resource_application_test.go | 2 + 4 files changed, 150 insertions(+) diff --git a/azuread/data_application.go b/azuread/data_application.go index 307d639d1c..b0b5f02dcf 100644 --- a/azuread/data_application.go +++ b/azuread/data_application.go @@ -70,6 +70,54 @@ func dataApplication() *schema.Resource { Computed: true, }, + "oauth2_permissions": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "admin_consent_description": { + Type: schema.TypeString, + Computed: true, + }, + + "admin_consent_display_name": { + Type: schema.TypeString, + Computed: true, + }, + + "id": { + Type: schema.TypeString, + Computed: true, + }, + + "is_enabled": { + Type: schema.TypeBool, + Computed: true, + }, + + "type": { + Type: schema.TypeString, + Computed: true, + }, + + "user_consent_description": { + Type: schema.TypeString, + Computed: true, + }, + + "user_consent_display_name": { + Type: schema.TypeString, + Computed: true, + }, + + "value": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "required_resource_access": { Type: schema.TypeList, Computed: true, @@ -175,5 +223,9 @@ func dataApplicationRead(d *schema.ResourceData, meta interface{}) error { return fmt.Errorf("Error setting `required_resource_access`: %+v", err) } + if oauth2Permissions, ok := application.AdditionalProperties["oauth2Permissions"].([]interface{}); ok { + d.Set("oauth2_permissions", flattenADApplicationOauth2Permissions(oauth2Permissions)) + } + return nil } diff --git a/azuread/data_application_test.go b/azuread/data_application_test.go index c4939e67ff..98e524903e 100644 --- a/azuread/data_application_test.go +++ b/azuread/data_application_test.go @@ -30,6 +30,8 @@ func TestAccAzureADApplicationDataSource_byObjectId(t *testing.T) { resource.TestCheckResourceAttr(dataSourceName, "reply_urls.#", "0"), resource.TestCheckResourceAttr(dataSourceName, "required_resource_access.#", "0"), resource.TestCheckResourceAttr(dataSourceName, "oauth2_allow_implicit_flow", "false"), + resource.TestCheckResourceAttr(dataSourceName, "oauth2_permissions.#", "1"), + resource.TestCheckResourceAttr(dataSourceName, "oauth2_permissions.0.admin_consent_description", fmt.Sprintf("Allow the application to access %s on behalf of the signed-in user.", fmt.Sprintf("acctest%s", id))), resource.TestCheckResourceAttrSet(dataSourceName, "application_id"), ), }, diff --git a/azuread/resource_application.go b/azuread/resource_application.go index dca00ce581..779f78f645 100644 --- a/azuread/resource_application.go +++ b/azuread/resource_application.go @@ -75,6 +75,55 @@ func resourceApplication() *schema.Resource { Computed: true, }, + "oauth2_permissions": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "admin_consent_description": { + Type: schema.TypeString, + Computed: true, + }, + + "admin_consent_display_name": { + Type: schema.TypeString, + Computed: true, + }, + + "id": { + Type: schema.TypeString, + Computed: true, + }, + + "is_enabled": { + Type: schema.TypeBool, + Computed: true, + }, + + "type": { + Type: schema.TypeString, + Computed: true, + }, + + "user_consent_description": { + Type: schema.TypeString, + Computed: true, + }, + + "user_consent_display_name": { + Type: schema.TypeString, + Computed: true, + }, + + "value": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "required_resource_access": { Type: schema.TypeSet, Optional: true, @@ -121,6 +170,7 @@ func resourceApplicationCreate(d *schema.ResourceData, meta interface{}) error { name := d.Get("name").(string) properties := graphrbac.ApplicationCreateParameters{ + AdditionalProperties: make(map[string]interface{}), DisplayName: &name, Homepage: expandADApplicationHomepage(d, name), IdentifierUris: tf.ExpandStringArrayPtr(d.Get("identifier_uris").([]interface{})), @@ -224,6 +274,10 @@ func resourceApplicationRead(d *schema.ResourceData, meta interface{}) error { return fmt.Errorf("Error setting `required_resource_access`: %+v", err) } + if oauth2Permissions, ok := resp.AdditionalProperties["oauth2Permissions"].([]interface{}); ok { + d.Set("oauth2_permissions", flattenADApplicationOauth2Permissions(oauth2Permissions)) + } + return nil } @@ -340,3 +394,43 @@ func flattenADApplicationResourceAccess(in *[]graphrbac.ResourceAccess) []interf return accesses } + +func flattenADApplicationOauth2Permissions(in []interface{}) []map[string]interface{} { + if in == nil { + return []map[string]interface{}{} + } + + result := make([]map[string]interface{}, 0, len(in)) + for _, oauth2Permissions := range in { + rawPermission := oauth2Permissions.(map[string]interface{}) + permission := make(map[string]interface{}) + if rawPermission["adminConsentDescription"] != nil { + permission["admin_consent_description"] = rawPermission["adminConsentDescription"] + } + if rawPermission["adminConsentDisplayName"] != nil { + permission["admin_consent_description"] = rawPermission["adminConsentDescription"] + } + if rawPermission["id"] != nil { + permission["id"] = rawPermission["id"] + } + if rawPermission["isEnabled"] != nil { + permission["is_enabled"] = rawPermission["isEnabled"].(bool) + } + if rawPermission["type"] != nil { + permission["type"] = rawPermission["type"] + } + if rawPermission["userConsentDescription"] != nil { + permission["user_consent_description"] = rawPermission["userConsentDescription"] + } + if rawPermission["userConsentDisplayName"] != nil { + permission["user_consent_display_name"] = rawPermission["userConsentDisplayName"] + } + if rawPermission["value"] != nil { + permission["value"] = rawPermission["value"] + } + + result = append(result, permission) + } + + return result +} diff --git a/azuread/resource_application_test.go b/azuread/resource_application_test.go index c714e30a86..8b41f3440d 100644 --- a/azuread/resource_application_test.go +++ b/azuread/resource_application_test.go @@ -26,6 +26,8 @@ func TestAccAzureADApplication_basic(t *testing.T) { testCheckADApplicationExists(resourceName), resource.TestCheckResourceAttr(resourceName, "name", fmt.Sprintf("acctest%s", id)), resource.TestCheckResourceAttr(resourceName, "homepage", fmt.Sprintf("https://acctest%s", id)), + resource.TestCheckResourceAttr(resourceName, "oauth2_permissions.#", "1"), + resource.TestCheckResourceAttr(resourceName, "oauth2_permissions.0.admin_consent_description", fmt.Sprintf("Allow the application to access %s on behalf of the signed-in user.", fmt.Sprintf("acctest%s", id))), resource.TestCheckResourceAttrSet(resourceName, "application_id"), ), }, From 29603f47515d18ed027515c5f4fe4cbb9715e815 Mon Sep 17 00:00:00 2001 From: Jan Schumann Date: Tue, 14 May 2019 15:26:00 +0200 Subject: [PATCH 2/4] add docs --- website/docs/d/application.html.markdown | 21 +++++++++++++++++++++ website/docs/r/application.html.markdown | 24 +++++++++++++++++++++++- 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/website/docs/d/application.html.markdown b/website/docs/d/application.html.markdown index 70f69564fc..a6175efa17 100644 --- a/website/docs/d/application.html.markdown +++ b/website/docs/d/application.html.markdown @@ -50,6 +50,7 @@ output "azure_ad_object_id" { * `required_resource_access` - A collection of `required_resource_access` blocks as documented below. +* `oauth2_permissions` - A collection of OAuth 2.0 permission scopes that the web API (resource) app exposes to client apps. Each permission is covered by a `oauth2_permission` block as documented below. --- @@ -66,3 +67,23 @@ output "azure_ad_object_id" { * `id` - The unique identifier for one of the `OAuth2Permission` or `AppRole` instances that the resource application exposes. * `type` - Specifies whether the id property references an `OAuth2Permission` or an `AppRole`. + +--- + +`oauth2_permission` block exports the following: + +* `id` - The unique identifier for one of the `OAuth2Permission` + +* `type` - The type of the permission + +* `admin_consent_description` - The description of the admin consent + +* `admin_consent_display_name` - The display name of the admin consent + +* `is_enabled` - Is this permission enabled? + +* `user_consent_description` - The description of the user consent + +* `user_consent_display_name` - The display name of the user consent + +* `value` - The name of this permission diff --git a/website/docs/r/application.html.markdown b/website/docs/r/application.html.markdown index 5bc0980fd6..fc54c547ce 100644 --- a/website/docs/r/application.html.markdown +++ b/website/docs/r/application.html.markdown @@ -69,7 +69,7 @@ The following arguments are supported: * `oauth2_allow_implicit_flow` - (Optional) Does this Azure AD Application allow OAuth2.0 implicit flow tokens? Defaults to `false`. -* `required_resource_access` - (Optional) A collection of `required_resource_access` blocks as documented below. +* `required_resource_access` - (Optional) A collection of `required_resource_access` blocks as documented below. --- @@ -93,6 +93,28 @@ The following attributes are exported: * `application_id` - The Application ID. +* `oauth2_permissions` - A collection of OAuth 2.0 permission scopes that the web API (resource) app exposes to client apps. Each permission is covered by a `oauth2_permission` block as documented below. + +--- + +`oauth2_permission` block exports the following: + +* `id` - The unique identifier for one of the `OAuth2Permission` + +* `type` - The type of the permission + +* `admin_consent_description` - The description of the admin consent + +* `admin_consent_display_name` - The display name of the admin consent + +* `is_enabled` - Is this permission enabled? + +* `user_consent_description` - The description of the user consent + +* `user_consent_display_name` - The display name of the user consent + +* `value` - The name of this permission + ## Import Azure Active Directory Applications can be imported using the `object id`, e.g. From 16115661885182d22185aa2121947e83b5b08b7e Mon Sep 17 00:00:00 2001 From: Jan Schumann Date: Wed, 15 May 2019 07:45:40 +0200 Subject: [PATCH 3/4] changes suggested by review --- azuread/data_application.go | 1 + azuread/resource_application.go | 33 ++++++++++++------------ website/docs/r/application.html.markdown | 18 ++++++------- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/azuread/data_application.go b/azuread/data_application.go index b0b5f02dcf..d8144e9a15 100644 --- a/azuread/data_application.go +++ b/azuread/data_application.go @@ -73,6 +73,7 @@ func dataApplication() *schema.Resource { "oauth2_permissions": { Type: schema.TypeList, Optional: true, + Computed: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "admin_consent_description": { diff --git a/azuread/resource_application.go b/azuread/resource_application.go index 779f78f645..5e7fef00cf 100644 --- a/azuread/resource_application.go +++ b/azuread/resource_application.go @@ -170,7 +170,6 @@ func resourceApplicationCreate(d *schema.ResourceData, meta interface{}) error { name := d.Get("name").(string) properties := graphrbac.ApplicationCreateParameters{ - AdditionalProperties: make(map[string]interface{}), DisplayName: &name, Homepage: expandADApplicationHomepage(d, name), IdentifierUris: tf.ExpandStringArrayPtr(d.Get("identifier_uris").([]interface{})), @@ -404,29 +403,29 @@ func flattenADApplicationOauth2Permissions(in []interface{}) []map[string]interf for _, oauth2Permissions := range in { rawPermission := oauth2Permissions.(map[string]interface{}) permission := make(map[string]interface{}) - if rawPermission["adminConsentDescription"] != nil { - permission["admin_consent_description"] = rawPermission["adminConsentDescription"] + if v := rawPermission["adminConsentDescription"]; v != nil { + permission["admin_consent_description"] = v } - if rawPermission["adminConsentDisplayName"] != nil { - permission["admin_consent_description"] = rawPermission["adminConsentDescription"] + if v := rawPermission["adminConsentDisplayName"]; v != nil { + permission["admin_consent_description"] = v } - if rawPermission["id"] != nil { - permission["id"] = rawPermission["id"] + if v := rawPermission["id"]; v != nil { + permission["id"] = v } - if rawPermission["isEnabled"] != nil { - permission["is_enabled"] = rawPermission["isEnabled"].(bool) + if v := rawPermission["isEnabled"]; v != nil { + permission["is_enabled"] = v.(bool) } - if rawPermission["type"] != nil { - permission["type"] = rawPermission["type"] + if v := rawPermission["type"]; v != nil { + permission["type"] = v } - if rawPermission["userConsentDescription"] != nil { - permission["user_consent_description"] = rawPermission["userConsentDescription"] + if v := rawPermission["userConsentDescription"]; v != nil { + permission["user_consent_description"] = v } - if rawPermission["userConsentDisplayName"] != nil { - permission["user_consent_display_name"] = rawPermission["userConsentDisplayName"] + if v := rawPermission["userConsentDisplayName"]; v != nil { + permission["user_consent_display_name"] = v } - if rawPermission["value"] != nil { - permission["value"] = rawPermission["value"] + if v := rawPermission["value"]; v != nil { + permission["value"] = v } result = append(result, permission) diff --git a/website/docs/r/application.html.markdown b/website/docs/r/application.html.markdown index fc54c547ce..773c3995ba 100644 --- a/website/docs/r/application.html.markdown +++ b/website/docs/r/application.html.markdown @@ -69,7 +69,7 @@ The following arguments are supported: * `oauth2_allow_implicit_flow` - (Optional) Does this Azure AD Application allow OAuth2.0 implicit flow tokens? Defaults to `false`. -* `required_resource_access` - (Optional) A collection of `required_resource_access` blocks as documented below. +* `required_resource_access` - (Optional) A collection of `required_resource_access` blocks as documented below. --- @@ -77,7 +77,7 @@ The following arguments are supported: * `resource_app_id` - (Required) The unique identifier for the resource that the application requires access to. This should be equal to the appId declared on the target resource application. -* `resource_access` - (Required) A collection of `resource_access` blocks as documented below +* `resource_access` - (Required) A collection of `resource_access` blocks as documented below. --- @@ -99,21 +99,21 @@ The following attributes are exported: `oauth2_permission` block exports the following: -* `id` - The unique identifier for one of the `OAuth2Permission` +* `id` - The unique identifier for one of the `OAuth2Permission`. -* `type` - The type of the permission +* `type` - The type of the permission. -* `admin_consent_description` - The description of the admin consent +* `admin_consent_description` - The description of the admin consent. -* `admin_consent_display_name` - The display name of the admin consent +* `admin_consent_display_name` - The display name of the admin consent. * `is_enabled` - Is this permission enabled? -* `user_consent_description` - The description of the user consent +* `user_consent_description` - The description of the user consent. -* `user_consent_display_name` - The display name of the user consent +* `user_consent_display_name` - The display name of the user consent. -* `value` - The name of this permission +* `value` - The name of this permission. ## Import From dd45a9a4465ed8eed5288b7cd092aad1f821a4c9 Mon Sep 17 00:00:00 2001 From: kt Date: Thu, 23 May 2019 12:09:49 -0700 Subject: [PATCH 4/4] remove optional flag and fix tests --- azuread/data_application_test.go | 2 +- azuread/resource_application.go | 1 - azuread/resource_application_test.go | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/azuread/data_application_test.go b/azuread/data_application_test.go index 98e524903e..6b93d8482e 100644 --- a/azuread/data_application_test.go +++ b/azuread/data_application_test.go @@ -31,7 +31,7 @@ func TestAccAzureADApplicationDataSource_byObjectId(t *testing.T) { resource.TestCheckResourceAttr(dataSourceName, "required_resource_access.#", "0"), resource.TestCheckResourceAttr(dataSourceName, "oauth2_allow_implicit_flow", "false"), resource.TestCheckResourceAttr(dataSourceName, "oauth2_permissions.#", "1"), - resource.TestCheckResourceAttr(dataSourceName, "oauth2_permissions.0.admin_consent_description", fmt.Sprintf("Allow the application to access %s on behalf of the signed-in user.", fmt.Sprintf("acctest%s", id))), + resource.TestCheckResourceAttr(dataSourceName, "oauth2_permissions.0.admin_consent_description", fmt.Sprintf("Access %s", fmt.Sprintf("acctest%s", id))), resource.TestCheckResourceAttrSet(dataSourceName, "application_id"), ), }, diff --git a/azuread/resource_application.go b/azuread/resource_application.go index 5e7fef00cf..2e182ee159 100644 --- a/azuread/resource_application.go +++ b/azuread/resource_application.go @@ -77,7 +77,6 @@ func resourceApplication() *schema.Resource { "oauth2_permissions": { Type: schema.TypeList, - Optional: true, Computed: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ diff --git a/azuread/resource_application_test.go b/azuread/resource_application_test.go index 8b41f3440d..a30fc7e04a 100644 --- a/azuread/resource_application_test.go +++ b/azuread/resource_application_test.go @@ -27,7 +27,7 @@ func TestAccAzureADApplication_basic(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "name", fmt.Sprintf("acctest%s", id)), resource.TestCheckResourceAttr(resourceName, "homepage", fmt.Sprintf("https://acctest%s", id)), resource.TestCheckResourceAttr(resourceName, "oauth2_permissions.#", "1"), - resource.TestCheckResourceAttr(resourceName, "oauth2_permissions.0.admin_consent_description", fmt.Sprintf("Allow the application to access %s on behalf of the signed-in user.", fmt.Sprintf("acctest%s", id))), + resource.TestCheckResourceAttr(resourceName, "oauth2_permissions.0.admin_consent_description", fmt.Sprintf("Access %s", fmt.Sprintf("acctest%s", id))), resource.TestCheckResourceAttrSet(resourceName, "application_id"), ), },