/// <summary>
        /// Gets distribution list members using group API.
        /// </summary>
        /// <param name="groupId">Distribution list id to get members list.</param>
        /// <param name="accessToken">Token to access MS graph.</param>
        /// <returns>DistributionListMember data model.</returns>
        private async Task <IEnumerable <DistributionListMember> > GetMembersList(string groupId, string accessToken)
        {
            GraphUtilityHelper graphClient = new GraphUtilityHelper(accessToken);
            var dlMemberList = await graphClient.GetMembersListAsync(groupId, this.logger);

            return(dlMemberList);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Gets Distribution List members from Graph and table storage.
        /// </summary>
        /// <param name="groupId">Distribution list id to filter records.</param>
        /// <param name="accessToken">Token to access MS graph.</param>
        /// <param name="userObjectId">User's Azure Active Directory Id.</param>
        /// <returns>A collection of distribution list members.</returns>
        public async Task <List <DistributionListMember> > GetMembersAsync(
            string groupId,
            string accessToken,
            string userObjectId)
        {
            this.graphClient = new GraphUtilityHelper(accessToken);

            List <DistributionListMember> distributionListMemberList = await this.graphClient.GetDistributionListMembersAsync(groupId, this.logger);

            IEnumerable <FavoriteDistributionListMemberTableEntity> favoriteDistributionListMemberEntity = await this.GetFavoriteMembersFromStorageAsync(userObjectId);

            foreach (DistributionListMember member in distributionListMemberList)
            {
                string distributionListMemberId = member.UserObjectId + groupId;
                foreach (FavoriteDistributionListMemberTableEntity entity in favoriteDistributionListMemberEntity)
                {
                    if (entity.DistributionListMemberId == distributionListMemberId)
                    {
                        member.IsPinned = true;
                    }
                }
            }

            return(distributionListMemberList
                   .Where(member => member.Type == "#microsoft.graph.group" ||
                          string.Equals(member.UserType, "member", StringComparison.OrdinalIgnoreCase))
                   .ToList());
        }
        /// <summary>
        /// Gets distribution list data from MS Graph based on search query.
        /// </summary>
        /// <param name="query">Search query used to filter distribution list.</param>
        /// <param name="accessToken">Token to access MS graph.</param>
        /// <returns>Distribution lists filtered with search query.</returns>
        public async Task <List <DistributionList> > GetDistributionListsAsync(
            string query, string accessToken)
        {
            GraphUtilityHelper graphClient = new GraphUtilityHelper(accessToken);
            var distributionList           = await graphClient.GetDistributionListsAsync(query, this.logger);

            return(distributionList.ToList());
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Updates department of UserData in Table Storage.
        /// </summary>
        /// <param name="partitionKey">Partition key.</param>
        /// <returns>A task that represents the work queued to execute.</returns>
        public async Task UpdateDepartmentAsync(string partitionKey)
        {
            try
            {
                if (!string.IsNullOrEmpty(partitionKey))
                {
                    // Get configuration values.
                    var microsoftAppId       = this.configuration["MicrosoftAppId"];
                    var microsoftAppPassword = this.configuration["MicrosoftAppPassword"];
                    var aadinstance          = this.configuration["AADInstance"];
                    var tenantid             = this.configuration["TenantId"];

                    // Generation client application.
                    IConfidentialClientApplication app = ConfidentialClientApplicationBuilder.Create(microsoftAppId)
                                                         .WithClientSecret(microsoftAppPassword)
                                                         .WithAuthority(new Uri(string.Format(CultureInfo.InvariantCulture, aadinstance, tenantid)))
                                                         .Build();

                    // Get all User data records from database.
                    IEnumerable <UserDataEntity> userDataEntities = await this.GetAllAsync(partitionKey);

                    List <UserDataEntity> usersDataBatchResults = new List <UserDataEntity>();
                    List <UserDataEntity> usersToBeUpdated      = new List <UserDataEntity>();

                    // Generate token for Graph API call.
                    string                accessToken          = this.GetGraphAPIAccessToken <string>(app);
                    GraphUtilityHelper    graphClient          = new GraphUtilityHelper(accessToken);
                    List <UserDataEntity> userDataEntitiesList = userDataEntities.ToList();
                    if (userDataEntitiesList.Count > 0)
                    {
                        IEnumerable <List <UserDataEntity> > updatedUserSplitList = ListExtensions.SplitList(userDataEntitiesList, BatchSplitCount);
                        foreach (var presenceBatch in updatedUserSplitList)
                        {
                            usersDataBatchResults.AddRange(await graphClient.GetUserDepartmentAsync(presenceBatch));
                        }
                    }

                    foreach (var user in usersDataBatchResults)
                    {
                        if (userDataEntitiesList.FirstOrDefault(x => x.AadId == user.AadId).Department != user.Department)
                        {
                            usersToBeUpdated.Add(user);
                        }
                    }

                    IEnumerable <List <UserDataEntity> > usersSplitList = ListExtensions.SplitList(usersToBeUpdated, UpdateSplitCount);
                    foreach (var updatelist in usersSplitList)
                    {
                        await this.CreateOrUpdateBatchAsync(updatelist);
                    }
                }
            }
            catch (Exception)
            {
                throw;
            }
        }
        /// <summary>
        /// Get User presence details in a batch.
        /// </summary>
        /// <param name="peoplePresenceData">Array of People Presence Data object used to get presence information.</param>
        /// <param name="accessToken">Token to access MS graph.</param>
        /// <returns>People Presence Data model data filled with presence information.</returns>
        public async Task <List <PeoplePresenceData> > GetBatchUserPresenceAsync(PeoplePresenceData[] peoplePresenceData, string accessToken)
        {
            List <PeoplePresenceData> peoplePresenceDataList         = new List <PeoplePresenceData>();
            List <PeoplePresenceData> peoplePresenceDataBatchResults = new List <PeoplePresenceData>();

            foreach (PeoplePresenceData member in peoplePresenceData)
            {
                string id = member.Id;
                if (!this.memoryCache.TryGetValue(id, out PeoplePresenceData peoplePresence))
                {
                    peoplePresence = new PeoplePresenceData()
                    {
                        UserPrincipalName = member.UserPrincipalName,
                        Id = member.Id,
                    };
                    peoplePresenceDataList.Add(peoplePresence);
                }
                else
                {
                    peoplePresenceDataBatchResults.Add(peoplePresence);
                }
            }

            if (peoplePresenceDataList.Count > 0)
            {
                var presenceBatches = peoplePresenceDataList.SplitList(BatchSplitCount);
                GraphUtilityHelper graphClientBeta = new GraphUtilityHelper(accessToken);

                foreach (var presenceBatch in presenceBatches)
                {
                    peoplePresenceDataBatchResults.AddRange(await graphClientBeta.GetUserPresenceAsync(presenceBatch, this.logger));
                }
            }
            else
            {
                this.logger.LogInformation($"GetBatchUserPresenceAsync. Presence of all users found in memory.");
            }

            return(peoplePresenceDataBatchResults);
        }
        /// <summary>
        /// Validate if user is a team owner using Microsoft Graph API.
        /// </summary>
        /// <param name="teamGroupId">AAD group id of the team in which bot is installed.</param>
        /// <returns>Returns response that represents whether logged in user is team owner or not.</returns>
        private async Task <ObjectResult> ValidateIfUserIsTeamOwnerAsync(string teamGroupId)
        {
            try
            {
                string accessToken = await this.GetAccessTokenAsync();

                if (string.IsNullOrEmpty(accessToken))
                {
                    this.logger.LogError("Token to access graph API is null.");
                    return(this.BadRequest("Token to access graph API is null."));
                }

                this.graphUtilityHelper = new GraphUtilityHelper(accessToken);
                var teamOwnerDetails = await this.graphUtilityHelper.GetTeamOwnerDetailsAsync(teamGroupId);

                if (teamOwnerDetails == null)
                {
                    this.logger.LogError(StatusCodes.Status404NotFound, "No data received corresponding to team owner.");
                    return(this.NotFound("No data received corresponding to team owner."));
                }

                var isTeamOwner = teamOwnerDetails.ToList().Exists(userId => userId.TeamOwnerId == this.UserObjectId);
                if (!isTeamOwner)
                {
                    this.logger.LogError(StatusCodes.Status403Forbidden, $"User {this.UserObjectId} is not a team owner. User is forbidden to access team goal details.");
                    return(this.StatusCode(StatusCodes.Status403Forbidden, $"User {this.UserObjectId} is not a team owner. User is forbidden to access team goal details."));
                }

                return(this.Ok(isTeamOwner));
            }
            catch (Exception ex)
            {
                this.logger.LogError(ex, "Error while getting team owner details from graph API.");
                throw;
            }
        }
        /// <summary>
        /// Get favorite distribution list details and members count from Graph.
        /// </summary>
        /// <param name="groupIds">List of Distribution List Ids.</param>
        /// <param name="accessToken">Token to access MS graph.</param>
        /// <returns>Count of members in distribution list.</returns>
        public async Task <List <DistributionList> > GetDistributionListDetailsFromGraphAsync(
            List <string> groupIds,
            string accessToken)
        {
            // MS Graph batch limit is 20
            // refer https://docs.microsoft.com/en-us/graph/known-issues#json-batching to known issues with Microsoft Graph batch APIs
            IEnumerable <List <string> > groupBatches         = groupIds.SplitList(BatchSplitCount);
            List <DistributionList>      distributionListList = new List <DistributionList>();
            GraphUtilityHelper           graphClient          = new GraphUtilityHelper(accessToken);

            foreach (List <string> groupBatch in groupBatches)
            {
                try
                {
                    distributionListList.AddRange(await graphClient.GetDistributionListDetailsAsync(groupBatch, this.logger));
                }
                catch (Exception ex)
                {
                    this.logger.LogError(ex, $"An error occurred in GetDistributionListDetailsFromGraphAsync.");
                }
            }

            return(distributionListList);
        }
        /// <summary>
        /// Gets online members count in a distribution list.
        /// </summary>
        /// <param name="groupId">Distribution list id.</param>
        /// <param name="accessToken">Token to access MS graph.</param>
        /// <returns><see cref="Task{TResult}"/>Online members count in distribution list.</returns>
        public async Task <int> GetDistributionListMembersOnlineCountAsync(string groupId, string accessToken)
        {
            try
            {
                int onlineMembersCount         = 0;
                GraphUtilityHelper graphClient = new GraphUtilityHelper(accessToken);
                var members = await this.GetMembersList(groupId, accessToken);

                var peoplePresenceDataList = new List <PeoplePresenceData>();

                foreach (DistributionListMember member in members)
                {
                    string id = member.UserObjectId;
                    if (!this.memoryCache.TryGetValue(id, out PeoplePresenceData peoplePresence))
                    {
                        peoplePresence = new PeoplePresenceData()
                        {
                            UserPrincipalName = member.UserPrincipalName,
                            Id = member.UserObjectId,
                        };
                        peoplePresenceDataList.Add(peoplePresence);
                    }
                    else
                    {
                        if (this.onlinePresenceOptions.Contains(peoplePresence.Availability))
                        {
                            onlineMembersCount++;
                        }
                    }
                }

                if (peoplePresenceDataList.Count > 0)
                {
                    MemoryCacheEntryOptions options = new MemoryCacheEntryOptions
                    {
                        AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(this.cacheOptions.Value.CacheInterval), // cache will expire in 300 seconds or 5 minutes
                    };

                    var presenceBatches = peoplePresenceDataList.SplitList(BatchSplitCount);

                    foreach (var presenceBatch in presenceBatches)
                    {
                        List <PeoplePresenceData> peoplePresenceResults = await graphClient.GetUserPresenceAsync(presenceBatch, this.logger);

                        for (int i = 0; i < peoplePresenceResults.Count; i++)
                        {
                            this.memoryCache.Set(peoplePresenceResults[i].Id, peoplePresenceResults[i], options);
                            if (this.onlinePresenceOptions.Contains(peoplePresenceResults[i].Availability.ToUpper()))
                            {
                                onlineMembersCount++;
                            }
                        }
                    }
                }
                else
                {
                    this.logger.LogInformation($"Presence of all users in group found in memory.");
                }

                return(onlineMembersCount);
            }
            catch (Exception ex)
            {
                this.logger.LogError(ex, $"GetDistributionListMembersOnlineCountAsync. An error occurred: {ex.Message}");
                throw;
            }
        }