/// <summary>
 /// Gets role assignments of the scope.
 /// </summary>
 /// <param name='operations'>
 /// Reference to the
 /// Microsoft.Azure.Management.Authorization.IRoleAssignmentOperations.
 /// </param>
 /// <param name='scope'>
 /// Required. Scope.
 /// </param>
 /// <param name='parameters'>
 /// Optional. List operation filters. If null will return all role
 /// assignments at, above or below the subscription.
 /// </param>
 /// <returns>
 /// Role assignment list operation result.
 /// </returns>
 public static Task <RoleAssignmentListResult> ListForScopeAsync(this IRoleAssignmentOperations operations, string scope, ListAssignmentsFilterParameters parameters)
 {
     return(operations.ListForScopeAsync(scope, parameters, CancellationToken.None));
 }
 /// <summary>
 /// Gets role assignments of the resource.
 /// </summary>
 /// <param name='operations'>
 /// Reference to the
 /// Microsoft.Azure.Management.Authorization.IRoleAssignmentOperations.
 /// </param>
 /// <param name='resourceGroupName'>
 /// Required. The name of the resource group.
 /// </param>
 /// <param name='identity'>
 /// Required. Resource identity.
 /// </param>
 /// <param name='parameters'>
 /// Optional. List operation filters. If null will return all role
 /// assignments at, above or below the resource.
 /// </param>
 /// <returns>
 /// Role assignment list operation result.
 /// </returns>
 public static Task <RoleAssignmentListResult> ListForResourceAsync(this IRoleAssignmentOperations operations, string resourceGroupName, ResourceIdentity identity, ListAssignmentsFilterParameters parameters)
 {
     return(operations.ListForResourceAsync(resourceGroupName, identity, parameters, CancellationToken.None));
 }
 /// <summary>
 /// Gets role assignments of the scope.
 /// </summary>
 /// <param name='operations'>
 /// Reference to the
 /// Microsoft.Azure.Management.Authorization.IRoleAssignmentOperations.
 /// </param>
 /// <param name='scope'>
 /// Required. Scope.
 /// </param>
 /// <param name='parameters'>
 /// Optional. List operation filters. If null will return all role
 /// assignments at, above or below the subscription.
 /// </param>
 /// <returns>
 /// Role assignment list operation result.
 /// </returns>
 public static RoleAssignmentListResult ListForScope(this IRoleAssignmentOperations operations, string scope, ListAssignmentsFilterParameters parameters)
 {
     return(Task.Factory.StartNew((object s) =>
     {
         return ((IRoleAssignmentOperations)s).ListForScopeAsync(scope, parameters);
     }
                                  , operations, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default).Unwrap().GetAwaiter().GetResult());
 }
        /// <summary>
        /// Filters role assignments based on the passed options.
        /// </summary>
        /// <param name="options">The filtering options</param>
        /// <returns>The filtered role assignments</returns>
        public List<PSRoleAssignment> FilterRoleAssignments(FilterRoleAssignmentsOptions options)
        {
            List<PSRoleAssignment> result = new List<PSRoleAssignment>();
            ListAssignmentsFilterParameters parameters = new ListAssignmentsFilterParameters();

            if (options.ADObjectFilter.HasFilter)
            {
                // Filter first by principal
                parameters.PrincipalId = string.IsNullOrEmpty(options.ADObjectFilter.Id) ? ActiveDirectoryClient.GetObjectId(options.ADObjectFilter) : Guid.Parse(options.ADObjectFilter.Id);
                result.AddRange(AuthorizationManagementClient.RoleAssignments.List(parameters)
                    .RoleAssignments.Select(r => r.ToPSRoleAssignment(this, ActiveDirectoryClient)));

                // Filter out by scope
                if (!string.IsNullOrEmpty(options.Scope))
                {
                    result.RemoveAll(r => !options.Scope.StartsWith(r.Scope));                    
                }
            }
            else if (!string.IsNullOrEmpty(options.Scope))
            {
                // Filter by scope and above directly
                parameters.AtScope = true;
                result.AddRange(AuthorizationManagementClient.RoleAssignments.ListForScope(options.Scope, parameters)
                    .RoleAssignments.Select(r => r.ToPSRoleAssignment(this, ActiveDirectoryClient)));
            }
            else
            {
                result.AddRange(AuthorizationManagementClient.RoleAssignments.List(parameters)
                    .RoleAssignments.Select(r => r.ToPSRoleAssignment(this, ActiveDirectoryClient)));
            }

            if (!string.IsNullOrEmpty(options.RoleDefinition))
            {
                result = result.Where(r => r.RoleDefinitionName.Equals(options.RoleDefinition, StringComparison.OrdinalIgnoreCase)).ToList();
            }

            return result;
        }
        /// <summary>
        /// Filters role assignments based on the passed options.
        /// </summary>
        /// <param name="options">The filtering options</param>
        /// <param name="currentSubscription">The current subscription</param>
        /// <returns>The filtered role assignments</returns>
        public List<PSRoleAssignment> FilterRoleAssignments(FilterRoleAssignmentsOptions options, string currentSubscription)
        {
            List<PSRoleAssignment> result = new List<PSRoleAssignment>();
            List<RoleAssignment> roleAssignments = new List<RoleAssignment>();
            ListAssignmentsFilterParameters parameters = new ListAssignmentsFilterParameters();

            PSADObject adObject = null;
            if (options.ADObjectFilter.HasFilter)
            {
                adObject = ActiveDirectoryClient.GetADObject(options.ADObjectFilter);
                if (adObject == null)
                {
                    throw new KeyNotFoundException(ProjectResources.PrincipalNotFound);
                }

                // Filter first by principal
                if (options.ExpandPrincipalGroups)
                {
                    if (!(adObject is PSADUser))
                    {
                        throw new InvalidOperationException(ProjectResources.ExpandGroupsNotSupported);
                    }

                    parameters.AssignedToPrincipalId = adObject.Id;
                }
                else
                {
                    parameters.PrincipalId = string.IsNullOrEmpty(options.ADObjectFilter.Id) ? adObject.Id : Guid.Parse(options.ADObjectFilter.Id);
                }

                var tempResult = AuthorizationManagementClient.RoleAssignments.List(parameters);
                roleAssignments.AddRange(tempResult.RoleAssignments.ToList());

                while (!string.IsNullOrWhiteSpace(tempResult.NextLink))
                {
                    tempResult = AuthorizationManagementClient.RoleAssignments.ListNext(tempResult.NextLink);
                    roleAssignments.AddRange(tempResult.RoleAssignments.ToList());
                }

                // Filter out by scope
                if (!string.IsNullOrEmpty(options.Scope))
                {
                    result.RemoveAll(r => !options.Scope.StartsWith(r.Scope, StringComparison.InvariantCultureIgnoreCase));
                }
            }
            else if (!string.IsNullOrEmpty(options.Scope))
            {
                // Filter by scope and above directly
                parameters.AtScope = true;

                var tempResult = AuthorizationManagementClient.RoleAssignments.ListForScope(options.Scope, parameters);
                roleAssignments.AddRange(tempResult.RoleAssignments.ToList());

                while (!string.IsNullOrWhiteSpace(tempResult.NextLink))
                {
                    tempResult = AuthorizationManagementClient.RoleAssignments.ListForScopeNext(tempResult.NextLink);
                    roleAssignments.AddRange(tempResult.RoleAssignments.ToList());
                }
            }
            else
            {
                var tempResult = AuthorizationManagementClient.RoleAssignments.List(parameters);
                roleAssignments.AddRange(tempResult.RoleAssignments.ToList());

                while (!string.IsNullOrWhiteSpace(tempResult.NextLink))
                {
                    tempResult = AuthorizationManagementClient.RoleAssignments.ListNext(tempResult.NextLink);
                    roleAssignments.AddRange(tempResult.RoleAssignments.ToList());
                }
            }

            // To look for RoleDefinitions at the stated scope - if scope is Null then default to subscription scope
            string scopeForRoleDefinitions = string.IsNullOrEmpty(options.Scope) ? AuthorizationHelper.GetSubscriptionScope(currentSubscription) : options.Scope;

            result.AddRange(roleAssignments.FilterRoleAssignmentsOnRoleId(options.RoleDefinitionId)
                .ToPSRoleAssignments(this, ActiveDirectoryClient, scopeForRoleDefinitions, options.ExcludeAssignmentsForDeletedPrincipals));

            if (!string.IsNullOrEmpty(options.RoleDefinitionName))
            {
                result = result.Where(r => r.RoleDefinitionName.Equals(options.RoleDefinitionName, StringComparison.OrdinalIgnoreCase)).ToList();
            }

            if (options.IncludeClassicAdministrators)
            {
                // Get classic administrator access assignments 
                List<ClassicAdministrator> classicAdministrators = AuthorizationManagementClient.ClassicAdministrators.List().ClassicAdministrators.ToList();
                List<PSRoleAssignment> classicAdministratorsAssignments = classicAdministrators.Select(a => a.ToPSRoleAssignment(currentSubscription)).ToList();

                // Filter by principal if provided
                if (options.ADObjectFilter.HasFilter)
                {
                    if (!(adObject is PSADUser))
                    {
                        throw new InvalidOperationException(ProjectResources.IncludeClassicAdminsNotSupported);
                    }

                    var userObject = adObject as PSADUser;
                    classicAdministratorsAssignments = classicAdministratorsAssignments.Where(c =>
                           c.DisplayName.Equals(userObject.UserPrincipalName, StringComparison.OrdinalIgnoreCase) ||
                           c.DisplayName.Equals(userObject.Mail, StringComparison.OrdinalIgnoreCase)).ToList();
                }

                result.AddRange(classicAdministratorsAssignments);
            }

            return result;
        }
 /// <summary>
 /// Gets role assignments of the scope.
 /// </summary>
 /// <param name='operations'>
 /// Reference to the
 /// Microsoft.Azure.Management.Authorization.IRoleAssignmentOperations.
 /// </param>
 /// <param name='scope'>
 /// Required. Scope.
 /// </param>
 /// <param name='parameters'>
 /// Optional. List operation filters. If null will return all role
 /// assignments at, above or below the subscription.
 /// </param>
 /// <returns>
 /// Role assignment list operation result.
 /// </returns>
 public static Task<RoleAssignmentListResult> ListForScopeAsync(this IRoleAssignmentOperations operations, string scope, ListAssignmentsFilterParameters parameters)
 {
     return operations.ListForScopeAsync(scope, parameters, CancellationToken.None);
 }
 /// <summary>
 /// Gets role assignments of the scope.
 /// </summary>
 /// <param name='operations'>
 /// Reference to the
 /// Microsoft.Azure.Management.Authorization.IRoleAssignmentOperations.
 /// </param>
 /// <param name='scope'>
 /// Required. Scope.
 /// </param>
 /// <param name='parameters'>
 /// Optional. List operation filters. If null will return all role
 /// assignments at, above or below the subscription.
 /// </param>
 /// <returns>
 /// Role assignment list operation result.
 /// </returns>
 public static RoleAssignmentListResult ListForScope(this IRoleAssignmentOperations operations, string scope, ListAssignmentsFilterParameters parameters)
 {
     return Task.Factory.StartNew((object s) => 
     {
         return ((IRoleAssignmentOperations)s).ListForScopeAsync(scope, parameters);
     }
     , operations, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default).Unwrap().GetAwaiter().GetResult();
 }
 /// <summary>
 /// Gets role assignments of the resource.
 /// </summary>
 /// <param name='operations'>
 /// Reference to the
 /// Microsoft.Azure.Management.Authorization.IRoleAssignmentOperations.
 /// </param>
 /// <param name='resourceGroupName'>
 /// Required. The name of the resource group.
 /// </param>
 /// <param name='identity'>
 /// Required. Resource identity.
 /// </param>
 /// <param name='parameters'>
 /// Optional. List operation filters. If null will return all role
 /// assignments at, above or below the resource.
 /// </param>
 /// <returns>
 /// Role assignment list operation result.
 /// </returns>
 public static Task<RoleAssignmentListResult> ListForResourceAsync(this IRoleAssignmentOperations operations, string resourceGroupName, ResourceIdentity identity, ListAssignmentsFilterParameters parameters)
 {
     return operations.ListForResourceAsync(resourceGroupName, identity, parameters, CancellationToken.None);
 }