public async Task <IActionResult> Status()
        {
            Identity currentIdentity = await GetIdentity();

            if (!currentIdentity.IsSiteAdmin())
            {
                return(Unauthorized());
            }

            List <string> currentLogins = new();

            foreach (var login in _identityManager.GetCurrentIdentities())
            {
                if (login is DiscordOAuthIdentity)
                {
                    try
                    {
                        var user = login.GetCurrentUser();
                        if (user == null)
                        {
                            currentLogins.Add($"Invalid user.");
                        }
                        else
                        {
                            currentLogins.Add($"{user.Username}#{user.Discriminator}");
                        }
                    }
                    catch (Exception e)
                    {
                        _logger.LogError(e, "Error getting logged in user.");
                        currentLogins.Add($"Invalid user.");
                    }
                }
            }

            StatusRepository repo = StatusRepository.CreateDefault(_serviceProvider);

            StatusDetail botDetails = repo.GetBotStatus();
            StatusDetail dbDetails  = await repo.GetDbStatus();

            StatusDetail cacheDetails = repo.GetCacheStatus();

            return(Ok(new
            {
                botStatus = botDetails,
                dbStatus = dbDetails,
                cacheStatus = cacheDetails,
                loginsInLast15Minutes = currentLogins,
                defaultLanguage = _config.GetDefaultLanguage(),
                trackedInvites = await InviteRepository.CreateDefault(_serviceProvider).CountInvites(),
                modCases = await ModCaseRepository.CreateDefault(_serviceProvider, currentIdentity).CountAllCases(),
                guilds = await GuildConfigRepository.CreateDefault(_serviceProvider).CountGuildConfigs(),
                automodEvents = await AutoModerationEventRepository.CreateDefault(_serviceProvider).CountEvents(),
                userNotes = await UserNoteRepository.CreateWithBotIdentity(_serviceProvider).CountUserNotes(),
                userMappings = await UserMapRepository.CreateWithBotIdentity(_serviceProvider).CountAllUserMaps(),
                apiTokens = await TokenRepository.CreateDefault(_serviceProvider).CountTokens(),
                nextCache = _scheduler.GetNextCacheSchedule(),
                cachedDataFromDiscord = _discordAPI.GetCache().Keys
            }));
        }
示例#2
0
        public async Task <IActionResult> GetInviteNetwork([FromQuery][Required] string inviteUrl)
        {
            InviteRepository inviteRepository = InviteRepository.CreateDefault(_serviceProvider);

            List <UserInvite> invites = await inviteRepository.GetInvitesByCode(inviteUrl);

            if (invites == null || invites.Count == 0)
            {
                return(NotFound());
            }

            await RequirePermission(invites[0].GuildId, DiscordPermission.Moderator);

            DiscordGuildView guild = new(_discordAPI.FetchGuildInfo(invites[0].GuildId, CacheBehavior.Default));

            List <UserInviteExpandedView> inviteViews = new();

            foreach (UserInvite invite in invites)
            {
                inviteViews.Add(new UserInviteExpandedView(
                                    invite,
                                    await _discordAPI.FetchUserInfo(invite.JoinedUserId, CacheBehavior.OnlyCache),
                                    await _discordAPI.FetchUserInfo(invite.InviteIssuerId, CacheBehavior.OnlyCache)
                                    ));
            }

            return(Ok(new
            {
                invites = inviteViews,
                guild
            }));
        }
示例#3
0
        public async Task Whois([Summary("user", "user to scan")] IUser user)
        {
            await Context.Interaction.RespondAsync("Getting WHOIS information...");

            IGuildUser member = null;

            try
            {
                member = Context.Guild.GetUser(user.Id);
            }
            catch (Exception) { }

            EmbedBuilder embed = new EmbedBuilder()
                                 .WithFooter($"UserId: {user.Id}")
                                 .WithTimestamp(DateTime.UtcNow)
                                 .WithColor(Color.Blue)
                                 .WithDescription(user.Mention);

            List <UserInvite> invites = await InviteRepository.CreateDefault(ServiceProvider).GetusedInvitesForUserAndGuild(user.Id, Context.Guild.Id);

            List <UserInvite> filteredInvites = invites.OrderByDescending(x => x.JoinedAt).ToList();

            if (member != null && member.JoinedAt != null)
            {
                filteredInvites = filteredInvites.FindAll(x => x.JoinedAt >= member.JoinedAt.Value.UtcDateTime);
            }
            StringBuilder joinedInfo = new();

            if (member != null)
            {
                joinedInfo.AppendLine(member.JoinedAt.Value.DateTime.ToDiscordTS());
            }
            if (filteredInvites.Count > 0)
            {
                UserInvite usedInvite = filteredInvites.First();
                joinedInfo.AppendLine(Translator.T().CmdWhoisUsedInvite(usedInvite.UsedInvite));
                if (usedInvite.InviteIssuerId != 0)
                {
                    joinedInfo.AppendLine(Translator.T().CmdWhoisInviteBy(usedInvite.InviteIssuerId));
                }
            }
            if (!string.IsNullOrEmpty(joinedInfo.ToString()))
            {
                embed.AddField(Translator.T().Joined(), joinedInfo.ToString(), true);
            }
            embed.AddField(Translator.T().Registered(), user.CreatedAt.DateTime.ToDiscordTS(), true);

            embed.WithAuthor(user);
            embed.WithThumbnailUrl(user.GetAvatarOrDefaultUrl(size: 1024));

            try
            {
                UserNote userNote = await UserNoteRepository.CreateDefault(ServiceProvider, CurrentIdentity).GetUserNote(Context.Guild.Id, user.Id);

                embed.AddField(Translator.T().UserNote(), userNote.Description.Truncate(1000), false);
            }
            catch (ResourceNotFoundException) { }

            List <UserMapping> userMappings = await UserMapRepository.CreateDefault(ServiceProvider, CurrentIdentity).GetUserMapsByGuildAndUser(Context.Guild.Id, user.Id);

            if (userMappings.Count > 0)
            {
                StringBuilder userMappingsInfo = new();
                foreach (UserMapping userMapping in userMappings.Take(5))
                {
                    ulong otherUser = userMapping.UserA == user.Id ? userMapping.UserB : userMapping.UserA;
                    userMappingsInfo.AppendLine($"<@{otherUser}> - {userMapping.Reason.Truncate(80)}");
                }
                if (userMappings.Count > 5)
                {
                    userMappingsInfo.Append("[...]");
                }
                embed.AddField($"{Translator.T().UserMaps()} [{userMappings.Count}]", userMappingsInfo.ToString(), false);
            }

            List <ModCase> cases = await ModCaseRepository.CreateWithBotIdentity(ServiceProvider).GetCasesForGuildAndUser(Context.Guild.Id, user.Id);

            List <ModCase> activeCases = cases.FindAll(c => c.PunishmentActive);

            if (cases.Count > 0)
            {
                StringBuilder caseInfo = new();
                foreach (ModCase modCase in cases.Take(5))
                {
                    caseInfo.Append($"[{modCase.CaseId} - {modCase.Title.Truncate(50)}]");
                    caseInfo.Append($"({Config.GetBaseUrl()}/guilds/{modCase.GuildId}/cases/{modCase.CaseId})\n");
                }
                if (cases.Count > 5)
                {
                    caseInfo.Append("[...]");
                }
                embed.AddField($"{Translator.T().Cases()} [{cases.Count}]", caseInfo.ToString(), false);

                if (activeCases.Count > 0)
                {
                    StringBuilder activeInfo = new();
                    foreach (ModCase modCase in activeCases.Take(5))
                    {
                        activeInfo.Append($"{modCase.GetPunishment(Translator)} ");
                        if (modCase.PunishedUntil != null)
                        {
                            activeInfo.Append($"({Translator.T().Until()} {modCase.PunishedUntil.Value.ToDiscordTS()}) ");
                        }
                        activeInfo.Append($"[{modCase.CaseId} - {modCase.Title.Truncate(50)}]");
                        activeInfo.Append($"({Config.GetBaseUrl()}/guilds/{modCase.GuildId}/cases/{modCase.CaseId})\n");
                    }
                    if (activeCases.Count > 5)
                    {
                        activeInfo.Append("[...]");
                    }
                    embed.AddField($"{Translator.T().ActivePunishments()} [{activeCases.Count}]", activeInfo.ToString(), false);
                }
            }
            else
            {
                embed.AddField($"{Translator.T().Cases()} [0]", Translator.T().CmdWhoisNoCases(), false);
            }

            await Context.Interaction.ModifyOriginalResponseAsync(message => { message.Content = ""; message.Embed = embed.Build(); });
        }
示例#4
0
        public async Task <IActionResult> GetUserNetwork([FromQuery][Required] ulong userId)
        {
            Identity currentIdentity = await GetIdentity();

            List <string>           modGuilds  = new();
            List <DiscordGuildView> guildViews = new();

            List <GuildConfig> guildConfigs = await GuildConfigRepository.CreateDefault(_serviceProvider).GetAllGuildConfigs();

            if (guildConfigs.Count == 0)
            {
                throw new BaseAPIException("No guilds registered");
            }
            foreach (GuildConfig guildConfig in guildConfigs)
            {
                if (await currentIdentity.HasPermissionOnGuild(DiscordPermission.Moderator, guildConfig.GuildId))
                {
                    modGuilds.Add(guildConfig.GuildId.ToString());
                    guildViews.Add(new DiscordGuildView(_discordAPI.FetchGuildInfo(guildConfig.GuildId, CacheBehavior.Default)));
                }
            }
            if (modGuilds.Count == 0)
            {
                return(Unauthorized());
            }

            DiscordUserView searchedUser = DiscordUserView.CreateOrDefault(await _discordAPI.FetchUserInfo(userId, CacheBehavior.IgnoreButCacheOnError));

            // invites
            // ===============================================================================================
            InviteRepository inviteRepository = InviteRepository.CreateDefault(_serviceProvider);

            List <UserInviteExpandedView> invited = new();

            foreach (UserInvite invite in await inviteRepository.GetInvitedForUser(userId))
            {
                if (!modGuilds.Contains(invite.GuildId.ToString()))
                {
                    continue;
                }
                invited.Add(new UserInviteExpandedView(
                                invite,
                                await _discordAPI.FetchUserInfo(invite.JoinedUserId, CacheBehavior.OnlyCache),
                                await _discordAPI.FetchUserInfo(invite.InviteIssuerId, CacheBehavior.OnlyCache)
                                ));
            }

            List <UserInviteExpandedView> invitedBy = new();

            foreach (UserInvite invite in await inviteRepository.GetusedInvitesForUser(userId))
            {
                if (!modGuilds.Contains(invite.GuildId.ToString()))
                {
                    continue;
                }
                invitedBy.Add(new UserInviteExpandedView(
                                  invite,
                                  await _discordAPI.FetchUserInfo(invite.JoinedUserId, CacheBehavior.OnlyCache),
                                  await _discordAPI.FetchUserInfo(invite.InviteIssuerId, CacheBehavior.OnlyCache)
                                  ));
            }

            // mappings
            // ===============================================================================================
            UserMapRepository userMapRepository         = UserMapRepository.CreateDefault(_serviceProvider, currentIdentity);
            List <UserMappingExpandedView> userMappings = new();

            foreach (UserMapping userMapping in await userMapRepository.GetUserMapsByUser(userId))
            {
                if (!modGuilds.Contains(userMapping.GuildId.ToString()))
                {
                    continue;
                }
                userMappings.Add(new UserMappingExpandedView(
                                     userMapping,
                                     await _discordAPI.FetchUserInfo(userMapping.UserA, CacheBehavior.OnlyCache),
                                     await _discordAPI.FetchUserInfo(userMapping.UserB, CacheBehavior.OnlyCache),
                                     await _discordAPI.FetchUserInfo(userMapping.CreatorUserId, CacheBehavior.OnlyCache)
                                     ));
            }

            ModCaseRepository             modCaseRepository             = ModCaseRepository.CreateDefault(_serviceProvider, currentIdentity);
            AutoModerationEventRepository autoModerationEventRepository = AutoModerationEventRepository.CreateDefault(_serviceProvider);
            UserNoteRepository            userNoteRepository            = UserNoteRepository.CreateDefault(_serviceProvider, currentIdentity);

            List <CaseView> modCases = (await modCaseRepository.GetCasesForUser(userId)).Where(x => modGuilds.Contains(x.GuildId.ToString())).Select(x => new CaseView(x)).ToList();
            List <AutoModerationEventView> modEvents = (await autoModerationEventRepository.GetAllEventsForUser(userId)).Where(x => modGuilds.Contains(x.GuildId.ToString())).Select(x => new AutoModerationEventView(x)).ToList();
            List <UserNoteView>            userNotes = (await userNoteRepository.GetUserNotesByUser(userId)).Where(x => modGuilds.Contains(x.GuildId.ToString())).Select(x => new UserNoteView(x)).ToList();

            return(Ok(new
            {
                guilds = guildViews,
                user = searchedUser,
                invited,
                invitedBy,
                modCases,
                modEvents,
                userMappings,
                userNotes
            }));
        }
示例#5
0
        public async Task Track([Summary("invite", "Either enter the invite code or the url")] string inviteCode)
        {
            await Context.Interaction.RespondAsync("Tracking invite code...");

            if (!inviteCode.ToLower().Contains("https://discord.gg/"))
            {
                inviteCode = $"https://discord.gg/{inviteCode}";
            }

            List <UserInvite> invites = await InviteRepository.CreateDefault(ServiceProvider).GetInvitesByCode(inviteCode);

            invites = invites.Where(x => x.GuildId == Context.Guild.Id).OrderByDescending(x => x.JoinedAt).ToList();

            DateTime?createdAt = null;
            IUser    creator   = null;
            int?     usages    = invites.Count;
            Dictionary <ulong, IUser> invitees = new();

            if (invites.Count > 0)
            {
                createdAt = invites[0].InviteCreatedAt;
                if (invites[0].InviteIssuerId != 0)
                {
                    creator = await DiscordAPI.FetchUserInfo(invites[0].InviteIssuerId, CacheBehavior.Default);
                }

                int count = 0;
                foreach (UserInvite invite in invites)
                {
                    if (count > 20)
                    {
                        break;
                    }
                    if (!invitees.ContainsKey(invite.JoinedUserId))
                    {
                        invitees.Add(invite.JoinedUserId, await DiscordAPI.FetchUserInfo(invite.JoinedUserId, CacheBehavior.Default));
                    }
                }
            }
            else
            {
                string code = inviteCode.Split("/").Last();
                try
                {
                    var fetchedInvite = await Context.Client.GetInviteAsync(code);

                    if (fetchedInvite.GuildId != Context.Guild.Id)
                    {
                        await Context.Interaction.ModifyOriginalResponseAsync(message => message.Content = Translator.T().CmdTrackInviteNotFromThisGuild());

                        return;
                    }
                    try
                    {
                        usages  = fetchedInvite.Uses;
                        creator = await DiscordAPI.FetchUserInfo(fetchedInvite.Inviter.Id, CacheBehavior.Default);
                    }
                    catch (NullReferenceException) { }
                }
                catch (HttpException e)
                {
                    if (e.HttpCode == HttpStatusCode.NotFound)
                    {
                        await Context.Interaction.ModifyOriginalResponseAsync(message => message.Content = Translator.T().CmdTrackCannotFindInvite());
                    }
                    else
                    {
                        await Context.Interaction.ModifyOriginalResponseAsync(message => message.Content = Translator.T().CmdTrackFailedToFetchInvite());
                    }
                    return;
                }
            }

            EmbedBuilder embed = new();

            embed.WithDescription(inviteCode);
            if (creator != null)
            {
                embed.WithAuthor(creator);
                if (createdAt.HasValue && createdAt.Value != default)
                {
                    embed.WithDescription(Translator.T().CmdTrackCreatedByAt(inviteCode, creator, createdAt.Value));
                }
                else
                {
                    embed.WithDescription(Translator.T().CmdTrackCreatedBy(inviteCode, creator));
                }
            }
            else if (createdAt.HasValue && createdAt.Value != default)
            {
                embed.WithDescription(Translator.T().CmdTrackCreatedAt(inviteCode, createdAt.Value));
            }

            StringBuilder usedBy = new();

            foreach (UserInvite invite in invites)
            {
                if (usedBy.Length > 900)
                {
                    break;
                }

                usedBy.Append("- ");
                if (invitees.ContainsKey(invite.JoinedUserId))
                {
                    IUser user = invitees[invite.JoinedUserId];
                    usedBy.Append($"`{user.Username}#{user.Discriminator}` ");
                }
                usedBy.AppendLine($"`{invite.JoinedUserId}` - {invite.JoinedAt.ToDiscordTS()}");
            }
            if (invites.Count == 0)
            {
                usedBy.Clear();
                usedBy.Append(Translator.T().CmdTrackNotTrackedYet());
            }

            embed.AddField(Translator.T().CmdTrackUsedBy(usages.GetValueOrDefault()), usedBy.ToString(), false);
            embed.WithFooter($"Invite: {inviteCode}");
            embed.WithTimestamp(DateTime.UtcNow);
            embed.WithColor(Color.Gold);

            await Context.Interaction.ModifyOriginalResponseAsync(message => { message.Content = ""; message.Embed = embed.Build(); });
        }
示例#6
0
        private async Task GuildMemberAddedHandler(SocketGuildUser member)
        {
            using var scope = _serviceProvider.CreateScope();

            var translator = scope.ServiceProvider.GetRequiredService <Translator>();
            await translator.SetContext(member.Guild.Id);

            // Refresh identity memberships
            IdentityManager identityManager = scope.ServiceProvider.GetRequiredService <IdentityManager>();

            foreach (Identity identity in identityManager.GetCurrentIdentities())
            {
                if (identity.GetCurrentUser().Id == member.Id)
                {
                    identity.AddGuildMembership(member);
                }
            }

            // Refresh member cache
            DiscordAPIInterface discordAPI = scope.ServiceProvider.GetRequiredService <DiscordAPIInterface>();

            discordAPI.AddOrUpdateCache(CacheKey.GuildMember(member.Guild.Id, member.Id), new CacheApiResponse(member));

            GuildConfig guildConfig;

            try
            {
                guildConfig = await GuildConfigRepository.CreateDefault(scope.ServiceProvider).GetGuildConfig(member.Guild.Id);
            }
            catch (ResourceNotFoundException)
            {
                return;
            }

            try
            {
                Punishments handler = scope.ServiceProvider.GetRequiredService <Punishments>();
                await handler.HandleMemberJoin(member);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Failed to handle punishment on member join.");
            }

            if (member.IsBot)
            {
                return;
            }

            List <TrackedInvite> newInvites = await FetchInvites(member.Guild);

            TrackedInvite usedInvite = null;

            try
            {
                usedInvite = InviteTracker.GetUsedInvite(member.Guild.Id, newInvites);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Failed to get used invite.");
            }

            InviteTracker.AddInvites(member.Guild.Id, newInvites);

            if (usedInvite != null)
            {
                UserInvite invite = new()
                {
                    GuildId         = member.Guild.Id,
                    JoinedUserId    = member.Id,
                    JoinedAt        = DateTime.UtcNow,
                    InviteIssuerId  = usedInvite.CreatorId,
                    InviteCreatedAt = usedInvite.CreatedAt,
                    TargetChannelId = usedInvite.TargetChannelId,
                    UsedInvite      = $"https://discord.gg/{usedInvite.Code}"
                };

                _logger.LogInformation($"User {member.Username}#{member.Discriminator} joined guild {member.Guild.Name} with ID: {member.Guild.Id} using invite {usedInvite.Code}");

                if (guildConfig.ExecuteWhoisOnJoin && !string.IsNullOrEmpty(guildConfig.ModInternalNotificationWebhook))
                {
                    string message;

                    if (invite.InviteIssuerId != 0 && invite.InviteCreatedAt != null)
                    {
                        message = translator.T().NotificationAutoWhoisJoinWithAndFrom(member, invite.InviteIssuerId, invite.InviteCreatedAt.Value, member.CreatedAt.DateTime, invite.UsedInvite);
                    }
                    else
                    {
                        message = translator.T().NotificationAutoWhoisJoinWith(member, member.CreatedAt.DateTime, invite.UsedInvite);
                    }

                    await discordAPI.ExecuteWebhook(guildConfig.ModInternalNotificationWebhook, null, message, AllowedMentions.None);
                }

                await InviteRepository.CreateDefault(scope.ServiceProvider).CreateInvite(invite);
            }
        }