예제 #1
0
 public CommentsView(ModCaseComment comment)
 {
     Id        = comment.Id;
     Message   = comment.Message;
     CreatedAt = comment.CreatedAt;
     UserId    = comment.UserId.ToString();
 }
        public async Task <IActionResult> CreateItem([FromRoute] ulong guildId, [FromRoute] int caseId, [FromBody] ModCaseCommentForCreateDto comment)
        {
            await RequirePermission(guildId, caseId, APIActionPermission.View);

            Identity currentIdentity = await GetIdentity();

            IUser currentUser = currentIdentity.GetCurrentUser();

            ModCase modCase = await ModCaseRepository.CreateDefault(_serviceProvider, currentIdentity).GetModCase(guildId, caseId);

            // suspects can only comment if last comment was not by him.
            if (!await currentIdentity.HasPermissionOnGuild(DiscordPermission.Moderator, guildId))
            {
                if (modCase.Comments.Any())
                {
                    if (modCase.Comments.Last().UserId == currentUser.Id)
                    {
                        throw new BaseAPIException("Already commented", APIError.LastCommentAlreadyFromSuspect);
                    }
                }
            }

            ModCaseComment createdComment = await ModCaseCommentRepository.CreateDefault(_serviceProvider, currentIdentity).CreateComment(guildId, caseId, comment.Message);

            return(StatusCode(201, new CommentsView(createdComment)));
        }
예제 #3
0
        private async Task AnnounceComment(ModCaseComment comment, IUser actor, RestAction action)
        {
            using var scope = _serviceProvider.CreateScope();

            _logger.LogInformation($"Announcing comment {comment.Id} in case {comment.ModCase.GuildId}/{comment.ModCase.CaseId}.");

            GuildConfig guildConfig = await GuildConfigRepository.CreateDefault(scope.ServiceProvider).GetGuildConfig(comment.ModCase.GuildId);

            if (!string.IsNullOrEmpty(guildConfig.ModInternalNotificationWebhook))
            {
                _logger.LogInformation($"Sending internal webhook for comment {comment.ModCase.GuildId}/{comment.ModCase.CaseId}/{comment.Id} to {guildConfig.ModInternalNotificationWebhook}.");

                try
                {
                    IUser user = await _discordAPI.FetchUserInfo(comment.UserId, CacheBehavior.Default);

                    EmbedBuilder embed = await comment.CreateCommentEmbed(action, actor, scope.ServiceProvider);

                    await _discordAPI.ExecuteWebhook(guildConfig.ModInternalNotificationWebhook, embed.Build());
                }
                catch (Exception e)
                {
                    _logger.LogError(e, $"Error while announcing comment {comment.ModCase.GuildId}/{comment.ModCase.CaseId}/{comment.Id} to {guildConfig.ModInternalNotificationWebhook}.");
                }
            }
        }
예제 #4
0
        public async Task AnnounceComment(ModCaseComment comment, User actor, RestAction action)
        {
            logger.LogInformation($"Announcing comment {comment.Id} in case {comment.ModCase.CaseId} in guild {comment.ModCase.GuildId}.");

            User discordUser = await discord.FetchUserInfo(comment.UserId);

            GuildConfig guildConfig = await dbContext.SelectSpecificGuildConfig(comment.ModCase.GuildId);

            if (!string.IsNullOrEmpty(guildConfig.ModInternalNotificationWebhook))
            {
                logger.LogInformation($"Sending internal webhook to {guildConfig.ModInternalNotificationWebhook}.");

                EmbedBuilder embed = NotificationEmbedCreator.CreateInternalCommentEmbed(comment, action, actor, discordUser, config.Value.ServiceBaseUrl);

                DiscordMessenger.SendEmbedWebhook(guildConfig.ModInternalNotificationWebhook, embed.Build());
                logger.LogInformation("Sent internal webhook.");
            }
        }
        public async Task <IActionResult> DeleteSpecificItem([FromRoute] ulong guildId, [FromRoute] int caseId, [FromRoute] int commentId)
        {
            await RequirePermission(guildId, caseId, APIActionPermission.View);

            Identity currentIdentity = await GetIdentity();

            IUser currentUser = currentIdentity.GetCurrentUser();

            var repo = ModCaseCommentRepository.CreateDefault(_serviceProvider, currentIdentity);

            ModCaseComment comment = await repo.GetSpecificComment(commentId);

            if (comment.UserId != currentUser.Id && !currentIdentity.IsSiteAdmin())
            {
                throw new UnauthorizedException();
            }

            await repo.DeleteComment(guildId, caseId, commentId);

            return(Ok());
        }
예제 #6
0
        public static async Task <EmbedBuilder> CreateCommentEmbed(this ModCaseComment comment, RestAction action, IUser actor, IServiceProvider provider)
        {
            var translator = provider.GetService <Translator>();

            await translator.SetContext(comment.ModCase.GuildId);

            EmbedBuilder embed = CreateBasicEmbed(action, provider, actor);

            if (actor != null)
            {
                embed.WithThumbnailUrl(actor.GetAvatarOrDefaultUrl());
            }

            switch (action)
            {
            case RestAction.Updated:
                embed.Description = translator.T().NotificationModcaseCommentsUpdate(actor);
                embed.Title       = $"**{translator.T().NotificationModcaseCommentsShortUpdate().ToUpper()}** - #{comment.ModCase.CaseId} {comment.ModCase.Title}";
                break;

            case RestAction.Deleted:
                embed.Description = translator.T().NotificationModcaseCommentsDelete(actor);
                embed.Title       = $"**{translator.T().NotificationModcaseCommentsShortDelete().ToUpper()}** - #{comment.ModCase.CaseId} {comment.ModCase.Title}";
                break;

            case RestAction.Created:
                embed.Description = translator.T().NotificationModcaseCommentsCreate(actor);
                embed.Title       = $"**{translator.T().NotificationModcaseCommentsShortCreate().ToUpper()}** - #{comment.ModCase.CaseId} {comment.ModCase.Title}";
                break;
            }

            // Message
            embed.AddField($"**{translator.T().Message()}**", comment.Message.Truncate(1000));

            // Footer
            embed.WithFooter($"UserId: {actor.Id} | CaseId: {comment.ModCase.CaseId}");

            return(embed);
        }
예제 #7
0
        public async Task <IActionResult> CreateItem([FromRoute] string guildid, [FromRoute] string caseid, [FromBody] ModCaseCommentForCreateDto comment)
        {
            logger.LogInformation($"{HttpContext.Request.Method} {HttpContext.Request.Path} | Incoming request.");
            Identity currentIdentity = await identityManager.GetIdentity(HttpContext);

            User currentUser = await currentIdentity.GetCurrentDiscordUser();

            if (currentUser == null)
            {
                logger.LogInformation($"{HttpContext.Request.Method} {HttpContext.Request.Path} | 401 Unauthorized.");
                return(Unauthorized());
            }
            ModCase modCase = await database.SelectSpecificModCase(guildid, caseid);

            if (!await currentIdentity.HasModRoleOrHigherOnGuild(guildid, this.database) && !config.Value.SiteAdminDiscordUserIds.Contains(currentUser.Id))
            {
                if (modCase == null)
                {
                    logger.LogInformation($"{HttpContext.Request.Method} {HttpContext.Request.Path} | 401 Unauthorized.");
                    return(Unauthorized());
                }
                else
                {
                    if (modCase.UserId != currentUser.Id)
                    {
                        logger.LogInformation($"{HttpContext.Request.Method} {HttpContext.Request.Path} | 401 Unauthorized.");
                        return(Unauthorized());
                    }
                }
            }
            // ========================================================

            if (await database.SelectSpecificGuildConfig(guildid) == null)
            {
                logger.LogInformation($"{HttpContext.Request.Method} {HttpContext.Request.Path} | 400 Guild not registered.");
                return(BadRequest("Guild not registered."));
            }

            if (modCase == null)
            {
                logger.LogInformation($"{HttpContext.Request.Method} {HttpContext.Request.Path} | 404 ModCase not found.");
                return(NotFound());
            }

            // normal user can only comment if no comments are there yet or last comment was not by him.
            if (!await currentIdentity.HasModRoleOrHigherOnGuild(guildid, this.database) && !config.Value.SiteAdminDiscordUserIds.Contains(currentUser.Id))
            {
                if (modCase.Comments.Any())
                {
                    if (modCase.Comments.Last().UserId == currentUser.Id)
                    {
                        logger.LogInformation($"{HttpContext.Request.Method} {HttpContext.Request.Path} | 400 Already commented.");
                        return(BadRequest("Already commented. Please wait for a response."));
                    }
                }
            }

            ModCaseComment commentToCreate = new ModCaseComment();

            commentToCreate.ModCase   = modCase;
            commentToCreate.UserId    = currentUser.Id;
            commentToCreate.Message   = comment.Message.Trim();
            commentToCreate.CreatedAt = DateTime.UtcNow;

            await database.SaveModCaseComment(commentToCreate);

            await database.SaveChangesAsync();

            logger.LogInformation($"{HttpContext.Request.Method} {HttpContext.Request.Path} | Sending notification.");
            try {
                await discordAnnouncer.AnnounceComment(commentToCreate, currentUser, RestAction.Created);
            }
            catch (Exception e) {
                logger.LogError(e, "Failed to announce comment.");
            }

            logger.LogInformation(HttpContext.Request.Method + " " + HttpContext.Request.Path + " | 201 Resource created.");
            return(StatusCode(201, new { id = commentToCreate.Id }));
        }
예제 #8
0
        public async Task <IActionResult> DeleteSpecificItem([FromRoute] string guildid, [FromRoute] string caseid, [FromRoute] int commentid)
        {
            logger.LogInformation($"{HttpContext.Request.Method} {HttpContext.Request.Path} | Incoming request.");
            Identity currentIdentity = await identityManager.GetIdentity(HttpContext);

            User currentUser = await currentIdentity.GetCurrentDiscordUser();

            if (currentUser == null)
            {
                logger.LogInformation($"{HttpContext.Request.Method} {HttpContext.Request.Path} | 401 Unauthorized.");
                return(Unauthorized());
            }
            ModCase modCase = await database.SelectSpecificModCase(guildid, caseid);

            if (!await currentIdentity.HasModRoleOrHigherOnGuild(guildid, this.database) && !config.Value.SiteAdminDiscordUserIds.Contains(currentUser.Id))
            {
                if (modCase == null)
                {
                    logger.LogInformation($"{HttpContext.Request.Method} {HttpContext.Request.Path} | 401 Unauthorized.");
                    return(Unauthorized());
                }
                else
                {
                    if (modCase.UserId != currentUser.Id)
                    {
                        logger.LogInformation($"{HttpContext.Request.Method} {HttpContext.Request.Path} | 401 Unauthorized.");
                        return(Unauthorized());
                    }
                }
            }
            // ========================================================

            if (await database.SelectSpecificGuildConfig(guildid) == null)
            {
                logger.LogInformation($"{HttpContext.Request.Method} {HttpContext.Request.Path} | 400 Guild not registered.");
                return(BadRequest("Guild not registered."));
            }

            if (modCase == null)
            {
                logger.LogInformation($"{HttpContext.Request.Method} {HttpContext.Request.Path} | 404 ModCase not found.");
                return(NotFound());
            }

            ModCaseComment comment = modCase.Comments.FirstOrDefault(x => x.Id == commentid);

            if (comment == null)
            {
                logger.LogInformation($"{HttpContext.Request.Method} {HttpContext.Request.Path} | 404 Comment not found.");
                return(NotFound());
            }

            if (comment.UserId != currentUser.Id && !config.Value.SiteAdminDiscordUserIds.Contains(currentUser.Id) && !await currentIdentity.HasModRoleOrHigherOnGuild(guildid, this.database))
            {
                logger.LogInformation($"{HttpContext.Request.Method} {HttpContext.Request.Path} | 401 Unauthorized.");
                return(Unauthorized());
            }

            database.DeleteSpecificModCaseComment(comment);
            await database.SaveChangesAsync();

            logger.LogInformation($"{HttpContext.Request.Method} {HttpContext.Request.Path} | Sending notification.");
            try {
                await discordAnnouncer.AnnounceComment(comment, currentUser, RestAction.Deleted);
            }
            catch (Exception e) {
                logger.LogError(e, "Failed to announce comment.");
            }

            logger.LogInformation($"{HttpContext.Request.Method} {HttpContext.Request.Path} | 200 Resource deleted.");
            return(Ok(new { id = comment.Id }));
        }
예제 #9
0
 public void DeleteSpecificModCaseComment(ModCaseComment comment)
 {
     context.ModCaseComments.Remove(comment);
 }
예제 #10
0
 public void UpdateModCaseComment(ModCaseComment comment)
 {
     context.ModCaseComments.Update(comment);
 }
예제 #11
0
        // ==================================================================================
        //
        // Comments
        //
        // ==================================================================================

        public async Task SaveModCaseComment(ModCaseComment comment)
        {
            await context.ModCaseComments.AddAsync(comment);
        }
        public static EmbedBuilder CreateInternalCommentEmbed(ModCaseComment comment, RestAction action, User actor, User discordUser = null, String serviceBaseUrl = null)
        {
            EmbedBuilder embed = CreateBasicEmbed(action);

            if (discordUser != null)
            {
                embed.ThumbnailUrl = discordUser.ImageUrl;
            }

            if (!string.IsNullOrEmpty(comment.Message))
            {
                embed.AddField("**Message**", comment.Message.Substring(0, Math.Min(comment.Message.Length, 1000)));
            }

            var footer = new EmbedFooterBuilder();

            footer.Text  = $"UserId: {comment.UserId} | ModCaseId: {comment.ModCase.CaseId}";
            embed.Footer = footer;

            StringBuilder description = new StringBuilder();

            switch (action)
            {
            case RestAction.Edited:
                description.Append($"A **Comment** by <@{comment.UserId}>");
                if (discordUser != null)
                {
                    description.Append($" ({discordUser.Username}#{discordUser.Discriminator})");
                }
                description.Append($" has been updated by <@{actor.Id}> ({actor.Username}#{actor.Discriminator}).");
                embed.Title = $"**UPDATED COMMENT** - #{comment.ModCase.CaseId} {comment.ModCase.Title}";
                break;

            case RestAction.Deleted:
                description.Append($"A **Comment** by <@{comment.UserId}>");
                if (discordUser != null)
                {
                    description.Append($" ({discordUser.Username}#{discordUser.Discriminator})");
                }
                description.Append($" has been deleted by <@{actor.Id}> ({actor.Username}#{actor.Discriminator}).");
                embed.Title = $"**DELETED COMMENT** - #{comment.ModCase.CaseId} {comment.ModCase.Title}";
                break;

            case RestAction.Created:
                description.Append($"A **Comment** has been created by <@{comment.UserId}> ({actor.Username}#{actor.Discriminator}).");
                embed.Title = $"**CREATED COMMENT** - #{comment.ModCase.CaseId} {comment.ModCase.Title}";
                break;
            }

            description.Append($"\nThis notification has been generated automatically.\n");
            description.Append($"Follow [this link]({serviceBaseUrl}/guilds/{comment.ModCase.GuildId}/cases/{comment.ModCase.CaseId}) to see the corresponding case.\n");
            description.Append($"[Contribute](https://github.com/zaanposni/discord-masz/blob/master/CONTRIBUTING.md) to this moderation tool.");

            embed.Description = description.ToString();

            if (!string.IsNullOrEmpty(serviceBaseUrl))
            {
                embed.Url = $"{serviceBaseUrl}/guilds/{comment.ModCase.GuildId}/cases/{comment.ModCase.CaseId}";
            }

            var author = new EmbedAuthorBuilder();

            author.IconUrl = $"{discordCdnBaseUrl}/avatars/{actor.Id}/{actor.Avatar}.png";
            author.Name    = actor.Username;
            embed.Author   = author;

            return(embed);
        }