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))); }
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}."); } } }
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()); }
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); }
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 })); }
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 })); }
public void DeleteSpecificModCaseComment(ModCaseComment comment) { context.ModCaseComments.Remove(comment); }
public void UpdateModCaseComment(ModCaseComment comment) { context.ModCaseComments.Update(comment); }
// ================================================================================== // // 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); }