public async Task <List <ChannelUserVm> > GetChannelUsersAsync(long channelId, long?navigationUserId, long?requestorId) { using (MessengerDbContext context = contextFactory.Create()) { if (navigationUserId == null) { navigationUserId = 0; } if (requestorId != null) { ChannelUser requestorChannelUser = await context.ChannelUsers .FirstOrDefaultAsync(opt => opt.ChannelUserRole >= ChannelUserRole.Administrator && opt.ChannelId == channelId && opt.UserId == requestorId) .ConfigureAwait(false); if (requestorChannelUser == null) { throw new PermissionDeniedException(); } } var channelUsers = await context.ChannelUsers .OrderByDescending(opt => opt.ChannelUserRole) .ThenBy(opt => opt.UserId) .Where(opt => opt.ChannelId == channelId && opt.UserId > navigationUserId && opt.Deleted == false) .ToListAsync() .ConfigureAwait(false); return(ChannelConverter.GetChannelUsers(channelUsers)); } }
public async Task <List <ChannelVm> > FindChannelsByStringQueryAsync(string searchQuery, long?navigationId, bool?direction = true) { ExpressionsHelper helper = new ExpressionsHelper(); var searchExpression = helper.GetChannelExpression(searchQuery); using (MessengerDbContext context = contextFactory.Create()) { var query = context.Channels .AsNoTracking() .Where(opt => !opt.Deleted) .Where(searchExpression); if (direction.GetValueOrDefault()) { query = query.OrderBy(opt => opt.ChannelId) .Where(opt => opt.ChannelId > navigationId.GetValueOrDefault()); } else { query = query.OrderByDescending(opt => opt.ChannelId) .Where(opt => opt.ChannelId < navigationId.GetValueOrDefault()); } var channels = await query.ToListAsync().ConfigureAwait(false); return(ChannelConverter.GetChannels(channels)); } }
public async Task <ChannelVm> EditChannelAsync(ChannelVm channel, long editorUserId) { using (MessengerDbContext context = contextFactory.Create()) { ChannelUser channelUser = await context.ChannelUsers .Include(opt => opt.Channel) .FirstOrDefaultAsync(opt => opt.ChannelId == channel.ChannelId && opt.UserId == editorUserId && opt.ChannelUserRole >= ChannelUserRole.Administrator) .ConfigureAwait(false); if (channelUser != null) { if (channelUser.ChannelUserRole == ChannelUserRole.Administrator && (channelUser.Banned || channelUser.Deleted)) { throw new PermissionDeniedException(); } channelUser.Channel = ChannelConverter.GetChannel(channelUser.Channel, channel); context.Update(channelUser.Channel); await context.SaveChangesAsync().ConfigureAwait(false); var editedChannel = ChannelConverter.GetChannel(channelUser.Channel); editedChannel.UserRole = channelUser.ChannelUserRole; editedChannel.SubscribersCount = await context.ChannelUsers.CountAsync(opt => opt.Deleted == false && opt.ChannelId == channel.ChannelId).ConfigureAwait(false); return(editedChannel); } throw new PermissionDeniedException(); } }
private async Task HandleChannelBlockSegmentAsync(BlockSegmentVm segment) { using (MessengerDbContext _context = CreateContext()) { using (var transaction = await _context.Database.BeginTransactionAsync().ConfigureAwait(false)) { try { ChannelBlockData blockData = (ChannelBlockData)segment.PublicData; var channel = await _context.Channels.FirstOrDefaultAsync(opt => opt.ChannelId == blockData.Channel.ChannelId).ConfigureAwait(false); if (channel == null) { channel = ChannelConverter.GetChannel(blockData.Channel); await _context.Channels.AddAsync(channel).ConfigureAwait(false); } else { channel = ChannelConverter.GetChannel(channel, blockData.Channel); _context.Channels.Update(channel); } await _context.SaveChangesAsync().ConfigureAwait(false); transaction.Commit(); } catch (Exception ex) { AddErrorMessage(nameof(HandleChannelBlockSegmentAsync), ex.ToString()); transaction.Rollback(); } } } }
public async Task CreateOrEditChannel() { var editableChannel = fillTestDbHelper.Channels.FirstOrDefault(); var validUser = editableChannel.ChannelUsers.FirstOrDefault(channelUser => channelUser.ChannelUserRole >= ChannelUserRole.Administrator); var invalidUser = editableChannel.ChannelUsers.FirstOrDefault(channelUser => channelUser.ChannelUserRole == ChannelUserRole.Subscriber); editableChannel.ChannelName = "Edited channel name"; var actualChannel = await createChannelsService.CreateOrEditChannelAsync(ChannelConverter.GetChannel(editableChannel), validUser.UserId, null); Assert.True(editableChannel.ChannelName == actualChannel.ChannelName); await Assert.ThrowsAsync <PermissionDeniedException>(async() => await createChannelsService.CreateOrEditChannelAsync(ChannelConverter.GetChannel(editableChannel), invalidUser.UserId, null)); var users = fillTestDbHelper.Users.Skip(1); var creator = fillTestDbHelper.Users.FirstOrDefault(); var newExpectedChannel = new ChannelVm { About = RandomExtensions.NextString(10), ChannelName = "Created channel", ChannelUsers = users.Select(user => new ChannelUserVm { UserId = user.Id, ChannelUserRole = ChannelUserRole.Subscriber }).ToList() }; var newActualChannel = await createChannelsService.CreateOrEditChannelAsync(newExpectedChannel, creator.Id, newExpectedChannel.ChannelUsers); Assert.True(newExpectedChannel.ChannelUsers.Count() + 1 == newActualChannel.ChannelUsers.Count()); }
public async Task <List <ChannelDto> > CreateChannelsAsync(List <ChannelDto> channels) { if (channels == null || !channels.Any()) { return(channels); } var channelsCondition = PredicateBuilder.New <Channel>(); var resultChannels = new List <Channel>(); channelsCondition = channels.Aggregate(channelsCondition, (current, value) => current.Or(opt => opt.ChannelId == value.ChannelId).Expand()); using (MessengerDbContext context = contextFactory.Create()) { var existingChannels = await context.Channels.Where(channelsCondition).ToListAsync().ConfigureAwait(false); var nonExistingChannels = channels.Where(channel => !existingChannels.Any(exChannel => exChannel.ChannelId == channel.ChannelId)); resultChannels.AddRange(existingChannels); if (nonExistingChannels != null) { var newChannels = ChannelConverter.GetChannels(nonExistingChannels.ToList()); await context.Channels.AddRangeAsync(newChannels).ConfigureAwait(false); resultChannels.AddRange(newChannels); await context.SaveChangesAsync().ConfigureAwait(false); } return(ChannelConverter.GetChannelsDto(resultChannels)); } }
public async Task <List <ChannelDto> > CreateOrUpdateUserChannelsAsync(List <ChannelDto> channels) { using (MessengerDbContext context = contextFactory.Create()) { var channelsCondition = PredicateBuilder.New <Channel>(); channelsCondition = channels.Aggregate(channelsCondition, (current, value) => current.Or(opt => opt.ChannelId == value.ChannelId).Expand()); List <Channel> existingChannels = await context.Channels .Include(opt => opt.ChannelUsers) .Where(channelsCondition) .ToListAsync() .ConfigureAwait(false); for (int i = 0; i < existingChannels.Count; i++) { ChannelDto editedChannel = channels.FirstOrDefault(opt => opt.ChannelId == existingChannels[i].ChannelId); existingChannels[i] = ChannelConverter.GetChannel(existingChannels[i], editedChannel); if (!editedChannel.ChannelUsers.IsNullOrEmpty()) { existingChannels[i].ChannelUsers = ChannelConverter.GetChannelUsers(editedChannel.ChannelUsers).ToList(); } } context.UpdateRange(existingChannels); List <ChannelDto> nonExistingChannels = channels.Where(channelDto => !existingChannels.Any(channel => channelDto.ChannelId == channel.ChannelId))?.ToList(); List <Channel> newChannels = ChannelConverter.GetChannels(nonExistingChannels); await context.AddRangeAsync(newChannels).ConfigureAwait(false); await context.SaveChangesAsync().ConfigureAwait(false); return(ChannelConverter.GetChannelsDto(newChannels.Concat(existingChannels))); } }
public async Task <List <ChannelVm> > GetChannelsAsync(IEnumerable <long> channelsId, long userId) { using (MessengerDbContext context = contextFactory.Create()) { var channelsCondition = PredicateBuilder.New <Channel>(); channelsCondition = channelsId.Aggregate(channelsCondition, (current, value) => current.Or(opt => opt.ChannelId == value).Expand()); List <Channel> channels = await context.Channels .AsNoTracking() .Where(channelsCondition) .Where(opt => opt.Deleted == false) .ToListAsync() .ConfigureAwait(false); if (channels == null || !channels.Any()) { throw new GetConversationsException(); } List <ChannelVm> resultChannels = ChannelConverter.GetChannels(channels).ToList(); var channelUsersCondition = PredicateBuilder.New <ChannelUser>(); channelUsersCondition = channels.Aggregate(channelUsersCondition, (current, value) => current.Or(opt => opt.ChannelId == value.ChannelId && opt.UserId == userId).Expand()); List <ChannelUser> channelUsers = await context .ChannelUsers .AsNoTracking() .Where(channelUsersCondition) .ToListAsync() .ConfigureAwait(false); foreach (var channel in resultChannels) { channel.SubscribersCount = await context.ChannelUsers.CountAsync(opt => opt.Deleted == false && opt.ChannelId == channel.ChannelId).ConfigureAwait(false); var currentChannelUser = channelUsers.FirstOrDefault(opt => opt.ChannelId == channel.ChannelId); if (currentChannelUser != null && !currentChannelUser.Deleted) { channel.UserRole = currentChannelUser.ChannelUserRole; } } var bannedUsers = channelUsers.Where(opt => opt.Banned)?.ToList(); if (bannedUsers != null) { foreach (var channelUser in bannedUsers) { var channel = resultChannels.FirstOrDefault(opt => opt.ChannelId == channelUser.ChannelId); if (channelUser.Banned && channel != null) { resultChannels.Remove(channel); } } } return(resultChannels); } }
public async Task <ChannelVm> GetChannelByIdAsync(long channelId) { using (MessengerDbContext context = contextFactory.Create()) { Channel channel = await context.Channels .FirstOrDefaultAsync(opt => opt.ChannelId == channelId).ConfigureAwait(false); return(ChannelConverter.GetChannel(channel)); } }
public void Add([NotNull] IChannel source) { var converter = new ChannelConverter(source); lock (_channels) lock (_mixerInput) { _channels.Add(source, converter); _mixerInput.AddMixerInput(converter); } }
public async Task <ChannelVm> CreateChannelAsync(ChannelVm channel, long creatorId, IEnumerable <ChannelUserVm> subscribers) { ChannelUser channelUser = new ChannelUser { ChannelUserRole = ChannelUserRole.Creator, SubscribedTime = DateTime.UtcNow.ToUnixTime(), UserId = creatorId, Deleted = false }; if (subscribers != null && await loadUsersService.IsUserBlacklisted(creatorId, subscribers.Select(opt => opt.UserId)).ConfigureAwait(false)) { throw new UserBlockedException(); } List <ChannelUser> channelUsers = new List <ChannelUser>() { channelUser }; if (subscribers != null) { channelUsers.AddRange(ChannelConverter.GetChannelUsers(subscribers.Where(opt => opt.UserId != creatorId))); } List <UserVm> users = await loadUsersService.GetUsersByIdAsync(channelUsers.Select(opt => opt.UserId)).ConfigureAwait(false); if (users.Count() < channelUsers.Count()) { throw new UserNotFoundException(); } Channel newChannel = new Channel { ChannelId = channel.ChannelId.GetValueOrDefault(await poolsService.GetChannelIdAsync().ConfigureAwait(false)), About = channel.About, Deleted = false, ChannelName = channel.ChannelName, CreationTime = DateTime.UtcNow.ToUnixTime(), Photo = channel.Photo, Tag = string.IsNullOrWhiteSpace(channel.Tag) ? RandomExtensions.NextString(10, "QWERTYUIOPASDFGHJKLZXCVBNM1234567890") : channel.Tag, NodesId = users.Select(opt => opt.NodeId.GetValueOrDefault()).Distinct().ToArray() }; using (MessengerDbContext context = contextFactory.Create()) { newChannel.ChannelUsers = channelUsers; var entityEntry = await context.Channels.AddAsync(newChannel).ConfigureAwait(false); await context.SaveChangesAsync().ConfigureAwait(false); var createdChannel = ChannelConverter.GetChannel(entityEntry.Entity); createdChannel.SubscribersCount = newChannel.ChannelUsers.Count(); return(createdChannel); } }
public async Task EditChannel() { var channel = fillTestDbHelper.Channels.FirstOrDefault(); var expectedChannel = ChannelConverter.GetChannelVm(ChannelConverter.GetChannelDto(channel)); expectedChannel.ChannelName = "Edited channel name"; expectedChannel.About = "Edited channel about"; expectedChannel.Tag = "EDITEDTAG"; var actualChannel = await updateChannelsService.EditChannelAsync(expectedChannel, channel.ChannelUsers.FirstOrDefault(opt => opt.ChannelUserRole >= ChannelUserRole.Administrator).UserId); Assert.True(expectedChannel.ChannelName == actualChannel.ChannelName && expectedChannel.About == actualChannel.About && expectedChannel.Tag != actualChannel.Tag); }
public async Task <List <ChannelUserVm> > GetAdministrationChannelUsersAsync(long channelId) { using (MessengerDbContext context = contextFactory.Create()) { var channelUsers = await context.ChannelUsers.Where(opt => opt.ChannelId == channelId && opt.Banned == false && opt.Deleted == false && opt.ChannelUserRole >= ChannelUserRole.Administrator) .ToListAsync() .ConfigureAwait(false); return(ChannelConverter.GetChannelUsers(channelUsers)); } }
private async Task HandleChannelUsersBlockSegmentAsync(BlockSegmentVm segment) { using (MessengerDbContext _context = CreateContext()) { using (var transaction = await _context.Database.BeginTransactionAsync().ConfigureAwait(false)) { try { if (TryDecryptPrivateData <ChannelUsersBlockData>(segment, out var blockData)) { var channelUserCondition = PredicateBuilder.New <ChannelUser>(); channelUserCondition = blockData.ChannelUsers.Aggregate(channelUserCondition, (current, value) => current.Or(opt => opt.ChannelId == value.ChannelId && opt.UserId == value.UserId).Expand()); var existingChannelUsers = await _context.ChannelUsers.Where(channelUserCondition).ToListAsync().ConfigureAwait(false); if (existingChannelUsers.Any()) { foreach (var channelUser in existingChannelUsers) { var editedChannelUser = blockData.ChannelUsers.FirstOrDefault(opt => opt.UserId == channelUser.UserId); if (editedChannelUser != null) { channelUser.Banned = editedChannelUser.Banned ?? channelUser.Banned; channelUser.Deleted = editedChannelUser.Deleted ?? channelUser.Deleted; channelUser.ChannelUserRole = editedChannelUser.ChannelUserRole ?? channelUser.ChannelUserRole; } } _context.ChannelUsers.UpdateRange(existingChannelUsers); } var nonExistingChannelUsers = blockData.ChannelUsers.Where(channelUser => !existingChannelUsers.Any(opt => opt.UserId == channelUser.UserId)); if (nonExistingChannelUsers.Any()) { var newChannelUsers = ChannelConverter.GetChannelUsers(nonExistingChannelUsers); await _context.ChannelUsers.AddRangeAsync(newChannelUsers).ConfigureAwait(false); } await _context.SaveChangesAsync().ConfigureAwait(false); transaction.Commit(); } } catch (Exception ex) { AddErrorMessage(nameof(HandleChannelUsersBlockSegmentAsync), ex.ToString()); transaction.Rollback(); } } } }
public async Task <List <ChannelDto> > GetChannelsWithSubscribersAsync(IEnumerable <long> channelsId) { using (MessengerDbContext context = contextFactory.Create()) { var channelsCondition = PredicateBuilder.New <Channel>(); channelsCondition = channelsId.Aggregate(channelsCondition, (current, value) => current.Or(opt => opt.ChannelId == value).Expand()); List <Channel> channels = await context.Channels .Include(opt => opt.ChannelUsers) .Where(channelsCondition) .ToListAsync() .ConfigureAwait(false); return(ChannelConverter.GetChannelsDto(channels)); } }
public async Task CreateOrEditChannelUsers() { var channel = fillTestDbHelper.Channels.FirstOrDefault(); var expectedChannelUsers = ChannelConverter.GetChannelUsers(channel.ChannelUsers); var validUser = channel.ChannelUsers.FirstOrDefault(opt => opt.ChannelUserRole >= ChannelUserRole.Administrator); var invalidUser = channel.ChannelUsers.FirstOrDefault(opt => opt.ChannelUserRole == ChannelUserRole.Subscriber); foreach (var channelUser in expectedChannelUsers) { if (channelUser.UserId != validUser.UserId) { channelUser.Deleted = true; } } var actualChannelUsers = await createChannelsService.CreateOrEditChannelUsersAsync(expectedChannelUsers, validUser.UserId); Assert.True(actualChannelUsers.All(opt => (opt.Deleted == true && opt.UserId != validUser.UserId) || opt.UserId == validUser.UserId)); await Assert.ThrowsAsync <PermissionDeniedException>(async() => await createChannelsService.CreateOrEditChannelUsersAsync(expectedChannelUsers, invalidUser.UserId)); }
public async Task <List <ChannelDto> > GetUserChannelsAsync(long userId) { using (MessengerDbContext context = contextFactory.Create()) { var query = from channel in context.Channels join channelUser in context.ChannelUsers on channel.ChannelId equals channelUser.ChannelId where channelUser.UserId == userId && !channelUser.Banned && !channelUser.Deleted && !channel.Deleted select channel; List <Channel> channels = await query.AsNoTracking() .Include(opt => opt.ChannelUsers) .Include(opt => opt.Messages) .ThenInclude(opt => opt.Attachments) .ToListAsync() .ConfigureAwait(false); return(ChannelConverter.GetChannelsDto(channels)); } }
public async Task <List <ChannelUserVm> > CreateOrEditChannelUsersAsync(List <ChannelUserVm> channelUsers, long requestorId) { try { using (MessengerDbContext context = contextFactory.Create()) { var channelUsersCondition = PredicateBuilder.New <ChannelUser>(); channelUsersCondition = channelUsers.Aggregate(channelUsersCondition, (current, value) => current.Or(opt => opt.ChannelId == value.ChannelId && opt.UserId == value.UserId).Expand()); List <ChannelUserVm> result = new List <ChannelUserVm>(); var existingChannelsUsers = ChannelConverter.GetChannelUsers(await context.ChannelUsers.Where(channelUsersCondition).ToListAsync().ConfigureAwait(false)); List <ChannelUserVm> nonExistingChannelUsers = new List <ChannelUserVm>(); if (existingChannelsUsers?.Any() ?? false) { var groups = existingChannelsUsers.GroupBy(opt => opt.ChannelId); foreach (var group in groups) { var edited = channelUsers.Where(opt => group.Any(p => p.ChannelId == opt.ChannelId && p.UserId == opt.UserId)).ToList(); result.AddRange(await updateChannelsService.EditChannelUsersAsync(edited, requestorId, group.Key.GetValueOrDefault()).ConfigureAwait(false)); } nonExistingChannelUsers = channelUsers.Where(opt => !existingChannelsUsers.Any(p => p.ChannelId == opt.ChannelId && p.UserId == opt.UserId)).ToList(); } else { nonExistingChannelUsers = channelUsers; } if (nonExistingChannelUsers?.Any() ?? false) { var newChannelUsers = ChannelConverter.GetChannelUsers(nonExistingChannelUsers).ToList(); await context.AddRangeAsync(newChannelUsers).ConfigureAwait(false); result.AddRange(ChannelConverter.GetChannelUsers(newChannelUsers)); } var channelGroups = channelUsers.GroupBy(opt => opt.ChannelId); foreach (var group in channelGroups) { var channelsNodesIds = await context.ChannelUsers .Where(opt => opt.ChannelId == group.Key) .Include(opt => opt.User) .Select(opt => opt.User.NodeId) .ToArrayAsync() .ConfigureAwait(false); var channel = await context.Channels.FindAsync(group.Key).ConfigureAwait(false); channel.NodesId = channelsNodesIds.Select(id => id.GetValueOrDefault()).Distinct().ToArray(); context.Channels.Update(channel); } await context.SaveChangesAsync().ConfigureAwait(false); return(result); } } catch (DbUpdateException ex) { if (ex.InnerException is PostgresException postgresException) { if (postgresException.ConstraintName == "FK_ChannelUsers_Channels_ChannelId") { throw new ConversationNotFoundException(); } if (postgresException.ConstraintName == "FK_ChannelUsers_Users_UserId") { throw new UserNotFoundException(); } } throw new AddOrRemoveChannelUsersException(); } }
public async Task <List <ChannelUserVm> > AddUsersToChannelAsync(List <long> usersId, long channelId, long requestorId) { using (MessengerDbContext context = contextFactory.Create()) { var usersCondition = PredicateBuilder.New <ChannelUser>(); usersCondition = usersId.Aggregate(usersCondition, (current, value) => current.Or(opt => opt.UserId == value).Expand()); var requestorUser = await context.ChannelUsers .FirstOrDefaultAsync(opt => opt.ChannelUserRole >= ChannelUserRole.Administrator && opt.ChannelId == channelId && opt.UserId == requestorId && opt.Channel.Deleted == false) .ConfigureAwait(false); if (requestorUser == null && (usersId.Count() > 1 || (usersId.Count() == 1 && usersId.ElementAt(0) != requestorId))) { throw new AddUserToChannelException(); } List <ChannelUser> existingUsers = await context.ChannelUsers .Where(usersCondition) .Where(opt => opt.ChannelId == channelId) .ToListAsync() .ConfigureAwait(false); List <long> nonExistingUsersId; if (existingUsers?.Any() ?? false) { nonExistingUsersId = usersId.Where(id => !existingUsers.Any(opt => opt.UserId == id)).ToList(); } else { nonExistingUsersId = usersId; } List <ChannelUser> newChannelUsers = nonExistingUsersId.Select(id => new ChannelUser { ChannelId = channelId, ChannelUserRole = ChannelUserRole.Subscriber, SubscribedTime = DateTime.UtcNow.ToUnixTime(), UserId = id }).ToList(); var users = await loadUsersService.GetUsersByIdAsync(nonExistingUsersId).ConfigureAwait(false); Channel channel = await context.Channels.FirstOrDefaultAsync(opt => opt.ChannelId == channelId).ConfigureAwait(false); channel.NodesId = channel.NodesId.Concat(users.Select(opt => opt.NodeId.GetValueOrDefault())).Distinct().ToArray(); context.Update(channel); var updatedUsers = new List <ChannelUser>(); if (existingUsers != null) { existingUsers.ForEach(channelUser => { if (!channelUser.Banned && channelUser.Deleted) { channelUser.Deleted = false; updatedUsers.Add(channelUser); } }); context.UpdateRange(existingUsers); } await context.AddRangeAsync(newChannelUsers).ConfigureAwait(false); await context.SaveChangesAsync().ConfigureAwait(false); return(ChannelConverter.GetChannelUsers(newChannelUsers.Concat(updatedUsers))); } }
public async Task <List <ChannelUserVm> > EditChannelUsersAsync(List <ChannelUserVm> channelUsers, long editorUserId, long channelId) { using (MessengerDbContext context = contextFactory.Create()) { ExpressionStarter <ChannelUser> channelUsersContidion = PredicateBuilder.New <ChannelUser>(); channelUsersContidion = channelUsers.Aggregate(channelUsersContidion, (current, value) => current.Or(opt => opt.ChannelId == value.ChannelId && opt.UserId == value.UserId)); Channel currentChannel = await context.Channels.FirstOrDefaultAsync(opt => opt.ChannelId == channelId && !opt.Deleted).ConfigureAwait(false); if (currentChannel == null) { throw new ObjectDoesNotExistsException("Channel not found."); } ChannelUser editorChannelUser = await context.ChannelUsers .AsNoTracking() .FirstOrDefaultAsync(opt => opt.ChannelId == channelId && opt.UserId == editorUserId) .ConfigureAwait(false); List <ChannelUser> editableChannelUsers = await context.ChannelUsers .Where(channelUsersContidion) .ToListAsync() .ConfigureAwait(false); if (editorChannelUser == null) { throw new PermissionDeniedException(); } if (editableChannelUsers == null || editableChannelUsers.Count < channelUsers.Count()) { throw new ObjectDoesNotExistsException("Editable users are not in channel."); } if (editorChannelUser.ChannelUserRole == ChannelUserRole.Subscriber && channelUsers.Count() != 1 && channelUsers.ElementAt(0).UserId != editorChannelUser.UserId || editorChannelUser.Banned) { throw new PermissionDeniedException(); } editableChannelUsers.ForEach(channelUser => { ChannelUserVm edited = channelUsers.FirstOrDefault(opt => opt.UserId == channelUser.UserId); if (editorChannelUser.ChannelUserRole > channelUser.ChannelUserRole) { channelUser.ChannelUserRole = edited.ChannelUserRole < editorChannelUser.ChannelUserRole && editorChannelUser.UserId != channelUser.UserId ? edited.ChannelUserRole.GetValueOrDefault() : channelUser.ChannelUserRole; channelUser.Deleted = channelUser.ChannelUserRole != ChannelUserRole.Creator && edited.Deleted.GetValueOrDefault(channelUser.Deleted); channelUser.Banned = channelUser.ChannelUserRole != ChannelUserRole.Creator && edited.Banned.GetValueOrDefault(channelUser.Banned); } else if (editorChannelUser.UserId == channelUser.UserId) { channelUser.ChannelUserRole = edited.ChannelUserRole < channelUser.ChannelUserRole ? edited.ChannelUserRole.GetValueOrDefault() : channelUser.ChannelUserRole; channelUser.Deleted = edited.Deleted.GetValueOrDefault(false); } else { throw new PermissionDeniedException(); } }); context.ChannelUsers.UpdateRange(editableChannelUsers); if (channelUsers.Any(opt => opt.Deleted.GetValueOrDefault() || opt.Banned.GetValueOrDefault())) { var query = from channel in context.Channels join channelUser in context.ChannelUsers on channel.ChannelId equals channelUser.ChannelId join user in context.Users on channelUser.UserId equals user.Id where channel.ChannelId == channelId && !channelUser.Banned && !channelUser.Deleted select user.NodeId; var channelNodesId = (await query.ToListAsync().ConfigureAwait(false)).Distinct(); currentChannel.NodesId = channelNodesId.Select(id => id.GetValueOrDefault()).ToArray(); context.Channels.Update(currentChannel); } await context.SaveChangesAsync().ConfigureAwait(false); return(ChannelConverter.GetChannelUsers(editableChannelUsers)); } }