From c8aaa2a13b74714e7c96c4d273ecf957491fef85 Mon Sep 17 00:00:00 2001 From: Jan Schumann Date: Thu, 23 May 2019 21:24:32 +0200 Subject: [PATCH] allow reading oauth2 permissions from aad application (#79) --- azuread/data_application.go | 53 ++++++++++++++ azuread/data_application_test.go | 2 + azuread/resource_application.go | 92 ++++++++++++++++++++++++ azuread/resource_application_test.go | 2 + website/docs/d/application.html.markdown | 21 ++++++ website/docs/r/application.html.markdown | 24 ++++++- 6 files changed, 193 insertions(+), 1 deletion(-) diff --git a/azuread/data_application.go b/azuread/data_application.go index 83da7763b0..0c9cee748c 100644 --- a/azuread/data_application.go +++ b/azuread/data_application.go @@ -73,6 +73,55 @@ func dataApplication() *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.TypeList, Computed: true, @@ -182,5 +231,9 @@ func dataApplicationRead(d *schema.ResourceData, meta interface{}) error { d.Set("group_membership_claims", groupMembershipClaims) } + 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 e9d8bc270c..f756c1f97b 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("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 03558996d3..b1318ed355 100644 --- a/azuread/resource_application.go +++ b/azuread/resource_application.go @@ -82,6 +82,54 @@ func resourceApplication() *schema.Resource { ), }, + "oauth2_permissions": { + Type: schema.TypeList, + 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, @@ -251,6 +299,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 } @@ -367,3 +419,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 v := rawPermission["adminConsentDescription"]; v != nil { + permission["admin_consent_description"] = v + } + if v := rawPermission["adminConsentDisplayName"]; v != nil { + permission["admin_consent_description"] = v + } + if v := rawPermission["id"]; v != nil { + permission["id"] = v + } + if v := rawPermission["isEnabled"]; v != nil { + permission["is_enabled"] = v.(bool) + } + if v := rawPermission["type"]; v != nil { + permission["type"] = v + } + if v := rawPermission["userConsentDescription"]; v != nil { + permission["user_consent_description"] = v + } + if v := rawPermission["userConsentDisplayName"]; v != nil { + permission["user_consent_display_name"] = v + } + if v := rawPermission["value"]; v != nil { + permission["value"] = v + } + + result = append(result, permission) + } + + return result +} diff --git a/azuread/resource_application_test.go b/azuread/resource_application_test.go index f6659c7112..e7170c9db6 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("Access %s", fmt.Sprintf("acctest%s", id))), resource.TestCheckResourceAttrSet(resourceName, "application_id"), ), }, diff --git a/website/docs/d/application.html.markdown b/website/docs/d/application.html.markdown index 4ddae6ae3b..02dd5724e4 100644 --- a/website/docs/d/application.html.markdown +++ b/website/docs/d/application.html.markdown @@ -52,6 +52,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. --- @@ -68,3 +69,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 08b8f7b11e..9829f97f76 100644 --- a/website/docs/r/application.html.markdown +++ b/website/docs/r/application.html.markdown @@ -79,7 +79,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. --- @@ -95,6 +95,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.