/// <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); }
/// <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()); }
/// <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; } }