diff --git a/docs/resources/group.md b/docs/resources/group.md index 5d2e226f9e..9dacad4148 100644 --- a/docs/resources/group.md +++ b/docs/resources/group.md @@ -14,6 +14,8 @@ When authenticated with a service principal, this resource requires one of the f If using the `assignable_to_role` property, this resource additionally requires one of the following application roles: `RoleManagement.ReadWrite.Directory` or `Directory.ReadWrite.All` +If specifying owners for a group, which are user principals, this resource additionally requires one of the following application roles: `User.Read.All`, `User.ReadWrite.All`, `Directory.Read.All` or `Directory.ReadWrite.All` + When authenticated with a user principal, this resource requires one of the following directory roles: `Groups Administrator`, `User Administrator` or `Global Administrator` ## Example Usage diff --git a/internal/services/applications/application_resource.go b/internal/services/applications/application_resource.go index c6551508b1..c124d3a30a 100644 --- a/internal/services/applications/application_resource.go +++ b/internal/services/applications/application_resource.go @@ -981,10 +981,8 @@ func applicationResourceCreate(ctx context.Context, d *schema.ResourceData, meta if callerObject == nil { return tf.ErrorDiagF(errors.New("returned callerObject was nil"), "Could not retrieve calling principal object %q", callerId) } - // TODO: remove this workaround for https://github.com/hashicorp/terraform-provider-azuread/issues/588 - //if callerObject.ODataId == nil { - // return tf.ErrorDiagF(errors.New("ODataId was nil"), "Could not retrieve calling principal object %q", callerId) - //} + + // @odata.id returned by API cannot be relied upon, so construct our own callerObject.ODataId = (*odata.Id)(utils.String(fmt.Sprintf("%s/v1.0/%s/directoryObjects/%s", client.BaseClient.Endpoint, client.BaseClient.TenantId, callerId))) @@ -997,29 +995,25 @@ func applicationResourceCreate(ctx context.Context, d *schema.ResourceData, meta // Retrieve and set the initial owners, which can be up to 20 in total when creating the application if v, ok := d.GetOk("owners"); ok { ownerCount := 0 - for _, ownerId := range v.(*schema.Set).List() { - if strings.EqualFold(ownerId.(string), callerId) { + for _, ownerIdRaw := range v.(*schema.Set).List() { + ownerId := ownerIdRaw.(string) + + // If the calling principal was found in the specified owners, we won't remove them later + if strings.EqualFold(ownerId, callerId) { removeCallerOwner = false continue } - ownerObject, _, err := directoryObjectsClient.Get(ctx, ownerId.(string), odata.Query{}) - if err != nil { - return tf.ErrorDiagF(err, "Could not retrieve owner principal object %q", ownerId) - } - if ownerObject == nil { - return tf.ErrorDiagF(errors.New("ownerObject was nil"), "Could not retrieve owner principal object %q", ownerId) + + ownerObject := msgraph.DirectoryObject{ + ODataId: (*odata.Id)(utils.String(fmt.Sprintf("%s/v1.0/%s/directoryObjects/%s", + client.BaseClient.Endpoint, client.BaseClient.TenantId, ownerId))), + ID: &ownerId, } - // TODO: remove this workaround for https://github.com/hashicorp/terraform-provider-azuread/issues/588 - //if ownerObject.ODataId == nil { - // return tf.ErrorDiagF(errors.New("ODataId was nil"), "Could not retrieve owner principal object %q", ownerId) - //} - ownerObject.ODataId = (*odata.Id)(utils.String(fmt.Sprintf("%s/v1.0/%s/directoryObjects/%s", - client.BaseClient.Endpoint, client.BaseClient.TenantId, ownerId))) if ownerCount < 19 { - ownersFirst20 = append(ownersFirst20, *ownerObject) + ownersFirst20 = append(ownersFirst20, ownerObject) } else { - ownersExtra = append(ownersExtra, *ownerObject) + ownersExtra = append(ownersExtra, ownerObject) } ownerCount++ } @@ -1082,7 +1076,6 @@ func applicationResourceCreate(ctx context.Context, d *schema.ResourceData, meta func applicationResourceUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { client := meta.(*clients.Client).Applications.ApplicationsClient - directoryObjectsClient := meta.(*clients.Client).Applications.DirectoryObjectsClient applicationId := d.Id() displayName := d.Get("display_name").(string) @@ -1175,21 +1168,11 @@ func applicationResourceUpdate(ctx context.Context, d *schema.ResourceData, meta if len(ownersToAdd) > 0 { newOwners := make(msgraph.Owners, 0) for _, ownerId := range ownersToAdd { - ownerObject, _, err := directoryObjectsClient.Get(ctx, ownerId, odata.Query{}) - if err != nil { - return tf.ErrorDiagF(err, "Could not retrieve owner principal object %q", ownerId) - } - if ownerObject == nil { - return tf.ErrorDiagF(errors.New("returned ownerObject was nil"), "Could not retrieve owner principal object %q", ownerId) - } - // TODO: remove this workaround for https://github.com/hashicorp/terraform-provider-azuread/issues/588 - //if ownerObject.ODataId == nil { - // return tf.ErrorDiagF(errors.New("ODataId was nil"), "Could not retrieve owner principal object %q", ownerId) - //} - ownerObject.ODataId = (*odata.Id)(utils.String(fmt.Sprintf("%s/v1.0/%s/directoryObjects/%s", - client.BaseClient.Endpoint, client.BaseClient.TenantId, ownerId))) - - newOwners = append(newOwners, *ownerObject) + newOwners = append(newOwners, msgraph.DirectoryObject{ + ODataId: (*odata.Id)(utils.String(fmt.Sprintf("%s/v1.0/%s/directoryObjects/%s", + client.BaseClient.Endpoint, client.BaseClient.TenantId, ownerId))), + ID: &ownerId, + }) } properties.Owners = &newOwners diff --git a/internal/services/serviceprincipals/service_principal_resource.go b/internal/services/serviceprincipals/service_principal_resource.go index f4abc26795..ed3f8f9808 100644 --- a/internal/services/serviceprincipals/service_principal_resource.go +++ b/internal/services/serviceprincipals/service_principal_resource.go @@ -421,10 +421,8 @@ func servicePrincipalResourceCreate(ctx context.Context, d *schema.ResourceData, if callerObject == nil { return tf.ErrorDiagF(errors.New("returned callerObject was nil"), "Could not retrieve calling principal object %q", callerId) } - // TODO: remove this workaround for https://github.com/hashicorp/terraform-provider-azuread/issues/588 - //if callerObject.ODataId == nil { - // return tf.ErrorDiagF(errors.New("ODataId was nil"), "Could not retrieve calling principal object %q", callerId) - //} + + // @odata.id returned by API cannot be relied upon, so construct our own callerObject.ODataId = (*odata.Id)(utils.String(fmt.Sprintf("%s/v1.0/%s/directoryObjects/%s", client.BaseClient.Endpoint, client.BaseClient.TenantId, callerId))) @@ -437,29 +435,25 @@ func servicePrincipalResourceCreate(ctx context.Context, d *schema.ResourceData, // Retrieve and set the initial owners, which can be up to 20 in total when creating the service principal if v, ok := d.GetOk("owners"); ok { ownerCount := 0 - for _, ownerId := range v.(*schema.Set).List() { - if strings.EqualFold(ownerId.(string), callerId) { + for _, ownerIdRaw := range v.(*schema.Set).List() { + ownerId := ownerIdRaw.(string) + + // If the calling principal was found in the specified owners, we won't remove them later + if strings.EqualFold(ownerId, callerId) { removeCallerOwner = false continue } - ownerObject, _, err := directoryObjectsClient.Get(ctx, ownerId.(string), odata.Query{}) - if err != nil { - return tf.ErrorDiagF(err, "Could not retrieve owner principal object %q", ownerId) - } - if ownerObject == nil { - return tf.ErrorDiagF(errors.New("ownerObject was nil"), "Could not retrieve owner principal object %q", ownerId) + + ownerObject := msgraph.DirectoryObject{ + ODataId: (*odata.Id)(utils.String(fmt.Sprintf("%s/v1.0/%s/directoryObjects/%s", + client.BaseClient.Endpoint, client.BaseClient.TenantId, ownerId))), + ID: &ownerId, } - // TODO: remove this workaround for https://github.com/hashicorp/terraform-provider-azuread/issues/588 - //if ownerObject.ODataId == nil { - // return tf.ErrorDiagF(errors.New("ODataId was nil"), "Could not retrieve owner principal object %q", ownerId) - //} - ownerObject.ODataId = (*odata.Id)(utils.String(fmt.Sprintf("%s/v1.0/%s/directoryObjects/%s", - client.BaseClient.Endpoint, client.BaseClient.TenantId, ownerId))) if ownerCount < 19 { - ownersFirst20 = append(ownersFirst20, *ownerObject) + ownersFirst20 = append(ownersFirst20, ownerObject) } else { - ownersExtra = append(ownersExtra, *ownerObject) + ownersExtra = append(ownersExtra, ownerObject) } ownerCount++ } @@ -513,7 +507,6 @@ func servicePrincipalResourceCreate(ctx context.Context, d *schema.ResourceData, func servicePrincipalResourceUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { client := meta.(*clients.Client).ServicePrincipals.ServicePrincipalsClient - directoryObjectsClient := meta.(*clients.Client).ServicePrincipals.DirectoryObjectsClient var tags []string if v, ok := d.GetOk("feature_tags"); ok && len(v.([]interface{})) > 0 && d.HasChange("feature_tags") { @@ -558,20 +551,11 @@ func servicePrincipalResourceUpdate(ctx context.Context, d *schema.ResourceData, if len(ownersToAdd) > 0 { newOwners := make(msgraph.Owners, 0) for _, ownerId := range ownersToAdd { - ownerObject, _, err := directoryObjectsClient.Get(ctx, ownerId, odata.Query{}) - if err != nil { - return tf.ErrorDiagF(err, "Could not retrieve owner principal object %q", ownerId) - } - if ownerObject == nil { - return tf.ErrorDiagF(errors.New("returned ownerObject was nil"), "Could not retrieve owner principal object %q", ownerId) - } - // TODO: remove this workaround for https://github.com/hashicorp/terraform-provider-azuread/issues/588 - //if ownerObject.ODataId == nil { - // return tf.ErrorDiagF(errors.New("ODataId was nil"), "Could not retrieve owner principal object %q", ownerId) - //} - ownerObject.ODataId = (*odata.Id)(utils.String(fmt.Sprintf("%s/v1.0/%s/directoryObjects/%s", - client.BaseClient.Endpoint, client.BaseClient.TenantId, ownerId))) - newOwners = append(newOwners, *ownerObject) + newOwners = append(newOwners, msgraph.DirectoryObject{ + ODataId: (*odata.Id)(utils.String(fmt.Sprintf("%s/v1.0/%s/directoryObjects/%s", + client.BaseClient.Endpoint, client.BaseClient.TenantId, ownerId))), + ID: &ownerId, + }) } properties.Owners = &newOwners