コード例 #1
0
        public async Task CheckBanAction(RuleExceedCheckCommand command)
        {
            var suspensionsForUser = await suspensionRepository.GetSuspensionsForUser(command.TwitchUsername).ConfigureAwait(false);

            if (suspensionsForUser.Count == 0)
            {
                return;
            }

            var userReport = new UserReport(command.TwitchUsername, suspensionsForUser);
            var channels   = await channelRepository.GetChannels().ConfigureAwait(false);

            foreach (var channel in channels.Where(x => x.ChannelRules.Count > 0))
            {
                foreach (var rule in channel.ChannelRules.Where(x => x.ActionOnTrigger == ChannelRuleAction.Ban))
                {
                    if (userReport.Exceeds(rule))
                    {
                        if (channel.SystemIsModerator && channel.ShouldListen)
                        {
                            await SendBanCommandFor(command.TwitchUsername, channel.ChannelName, rule.RuleName).ConfigureAwait(false);
                        }
                        else
                        {
                            logger.LogInformation("Channel Rule triggered ban, but channel does not have moderation / listening enabled for: {arg}", channel.ChannelName);
                        }
                    }
                }
            }
        }
コード例 #2
0
        private async Task MarkActiveSuspensionsForUserAsUndone(string username, string undoneBy, DateTime timeOfSuspension, IMessageDispatcher messageDispatcher)
        {
            var suspensionsForUser = await suspensionRepository.GetSuspensionsForUser(username).ConfigureAwait(false);

            foreach (var activeSuspension in suspensionsForUser.Where(x => x.IsActive(timeOfSuspension)))
            {
                activeSuspension.MarkSuspensionAsUndone(undoneBy);
                await suspensionRepository.Save(activeSuspension).ConfigureAwait(false);

                await messageDispatcher.Publish(new SuspensionUpdatedEvent
                {
                    ChannelOfOrigin = activeSuspension.ChannelOfOrigin,
                    SuspensionId    = activeSuspension.SuspensionId
                }).ConfigureAwait(false);
            }
        }
コード例 #3
0
        public async Task <IResult <Suspension> > UpdateAuditState(Guid suspensionId, bool audited, IApplicationContext context)
        {
            var fetch = await RetrieveSuspensionAndCheckAccess(suspensionId, context).ConfigureAwait(false);

            if (fetch.State != ResultState.Success)
            {
                return(fetch);
            }

            var suspension = fetch.Data;

            if (suspension.SuspensionType == SuspensionType.Ban)
            {
                var suspensionsForUser = await suspensionRepository.GetSuspensionsForUser(suspension.Username).ConfigureAwait(false);

                foreach (var ban in suspensionsForUser.Where(x => x.SuspensionType == SuspensionType.Ban &&
                                                             x.Audited &&
                                                             string.Equals(x.ChannelOfOrigin, suspension.ChannelOfOrigin, StringComparison.OrdinalIgnoreCase)).ToList())
                {
                    if (ban.Timestamp < suspension.Timestamp && !ban.InvalidSuspension)
                    {
                        ban.UpdateValidity(true, "Invalid because a new ban overwrites", context, datetimeProvider.UtcNow);
                        await suspensionRepository.Save(ban).ConfigureAwait(false);
                        await PublishSuspensionUpdatedEvent(ban).ConfigureAwait(false);
                    }
                }
            }

            suspension.UpdateAuditedState(audited, context, datetimeProvider.UtcNow);
            await suspensionRepository.Save(suspension).ConfigureAwait(false);

            if (suspension.Audited && !suspension.InvalidSuspension)
            {
                await PublishSuspensionAuditedEvent(suspension).ConfigureAwait(false);
            }

            await PublishSuspensionUpdatedEvent(suspension).ConfigureAwait(false);

            return(Result <Suspension> .Succeeded(suspension));
        }
コード例 #4
0
        public async Task IssueBanFor(string username, string channelToBanFrom, string systemReason)
        {
            var suspensionsForUser = await suspensionRepository.GetSuspensionsForUser(username).ConfigureAwait(false);

            var suspensionsForUserInChannel = suspensionsForUser.Where(x => string.Equals(x.ChannelOfOrigin, channelToBanFrom, StringComparison.OrdinalIgnoreCase));

            if (suspensionsForUserInChannel.Any(x => x.SuspensionType == SuspensionType.Ban && !x.InvalidSuspension && x.Audited))
            {
                logger.LogInformation("{arg} has already been banned from {arg2}", username, channelToBanFrom);
                return;
            }

            client.BanUser(username, channelToBanFrom, systemReason);
        }
コード例 #5
0
        public async Task <IResult <List <UserRulesExceeded> > > GetUsersWhoExceedsRules(string channelName, IApplicationContext context)
        {
            var suspensionsForSystem = await suspensionRepository.GetSuspensions(datetimeProvider.UtcNow.AddYears(-1)).ConfigureAwait(false);

            var usersFromSuspensions = suspensionsForSystem.Select(x => x.Username);

            var channel = await channelRepository.GetChannel(channelName).ConfigureAwait(false);

            if (!context.HaveAccessTo(channel))
            {
                return(Result <List <UserRulesExceeded> > .Unauthorized());
            }

            var allSuspensionsForChannel = await suspensionRepository.GetSuspensionsForChannel(channelName).ConfigureAwait(false);

            var allValidAuditedSuspensionForChannel = allSuspensionsForChannel.Where(x => !x.InvalidSuspension && x.Audited);

            var usersWhoExceeded = new List <UserRulesExceeded>();

            foreach (var user in usersFromSuspensions.Distinct(StringComparer.OrdinalIgnoreCase))
            {
                // If we already have a ban
                if (allValidAuditedSuspensionForChannel.Any(x => string.Equals(x.Username, user, StringComparison.OrdinalIgnoreCase) && x.SuspensionType == SuspensionType.Ban))
                {
                    continue;
                }

                var suspensionsForUser = await suspensionRepository.GetSuspensionsForUser(user).ConfigureAwait(false);

                var report = new UserReport(user, suspensionsForUser);

                foreach (var rule in channel.ChannelRules.Where(x => x.ActionOnTrigger == ChannelRuleAction.Ban))
                {
                    if (report.Exceeds(rule))
                    {
                        var userRulesExceeded = usersWhoExceeded.Find(x => string.Equals(x.Username, user, StringComparison.OrdinalIgnoreCase)) ?? new UserRulesExceeded {
                            Username = user
                        };

                        usersWhoExceeded.Remove(userRulesExceeded);

                        userRulesExceeded.RulesBroken.Add(rule);
                        usersWhoExceeded.Add(userRulesExceeded);
                    }
                }
            }

            return(Result <List <UserRulesExceeded> > .Succeeded(usersWhoExceeded));
        }
コード例 #6
0
        public async Task <IResult <UserReport> > GetUserReportFor(string username)
        {
            var suspensionsForUser = await suspensionRepository.GetSuspensionsForUser(username).ConfigureAwait(false);

            if (suspensionsForUser.Count == 0)
            {
                return(Result <UserReport> .NoContentFound());
            }

            var userReport = new UserReport(username, suspensionsForUser);

            if (userReport.Suspensions.Count == 0)
            {
                return(Result <UserReport> .NoContentFound());
            }

            return(Result <UserReport> .Succeeded(userReport));
        }
コード例 #7
0
        public async Task SendNotification(string username, string channelOfOrigin, Guid ruleId)
        {
            var channel = await channelRepository.GetChannel(channelOfOrigin).ConfigureAwait(false);

            var ruleThatWasBroken = channel.ChannelRules.FirstOrDefault(x => x.RuleId == ruleId);

            var suspensionsForUser = await suspensionRepository.GetSuspensionsForUser(username).ConfigureAwait(false);

            if (UserHasActiveBanInTheChannel())
            {
                logger.LogInformation($"{username} already has active bans in {channelOfOrigin}, no need to send notification to discord");
                return;
            }

            var ownerOfChannel = await userRepository.GetByTwitchUsername(channel.ChannelName).ConfigureAwait(false);

            if (ownerOfChannel?.DiscordEnabled == true)
            {
                logger.LogInformation($"Sent discord notification to {ownerOfChannel.TwitchUsername} (Owner of channel)");

                await discordMessageClient.SendDmToUser(ownerOfChannel.DiscordUserId, $"{username}, has been spotted in your channel, they have exceeded the rule: {ruleThatWasBroken.RuleName}").ConfigureAwait(false);
            }

            foreach (var mod in channel.Moderators)
            {
                var user = await userRepository.GetByTwitchUsername(mod).ConfigureAwait(false);

                if (user?.DiscordEnabled == true)
                {
                    logger.LogInformation($"Sent discord notification to {user.TwitchUsername}");

                    await discordMessageClient.SendDmToUser(user.DiscordUserId, $"{username}, has been spotted in {channel.ChannelName}, they have exceeded the rule: {ruleThatWasBroken.RuleName}").ConfigureAwait(false);
                }
            }

            bool UserHasActiveBanInTheChannel()
            {
                return(suspensionsForUser.Any(x =>
                                              string.Equals(x.ChannelOfOrigin, channelOfOrigin, StringComparison.OrdinalIgnoreCase) &&
                                              x.SuspensionType == SuspensionType.Ban &&
                                              x.Audited &&
                                              !x.InvalidSuspension));
            }
        }