Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/reports #22

Merged
merged 10 commits into from
Mar 24, 2024
Merged
3 changes: 3 additions & 0 deletions core/.env.template
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,6 @@ CONTAINER_DIR=/app/volume
CDN_URL=http://localhost:6464

FRONTEND_BASE_URL=http://localhost:3000

RATE_LIMIT_TIME_WINDOW_SECONDS=10
RATE_LIMIT_MAX_REQUESTS=4
17 changes: 16 additions & 1 deletion core/Controllers/EventsController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,17 @@

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.OutputCaching;
using Microsoft.AspNetCore.RateLimiting;

namespace api.core.controllers;

[ApiController]
[Route("api/events")]
public class EventsController(ILogger<EventsController> logger, IEventService eventService, ITagService tagService) : ControllerBase
public class EventsController(ILogger<EventsController> logger, IEventService eventService, ITagService tagService, IReportService reportService) : ControllerBase
{

public const string RATE_LIMITING_POLICY_NAME = "EventsControllerRateLimitPolicy";

/// <summary>
/// Get events by date, activity area and tags
/// </summary>
Expand Down Expand Up @@ -61,6 +65,17 @@ public IActionResult GetEvent(Guid id)
});
}

[HttpPost("{id}/reports")]
[EnableRateLimiting(RATE_LIMITING_POLICY_NAME)]
public IActionResult ReportEvent(Guid id, [FromBody] CreateReportRequestDTO request)
{
logger.LogInformation($"Reporting event {id}");

reportService.ReportEvent(id, request);

return Ok();
}

[HttpGet("tags")]
public IActionResult GetTags()
{
Expand Down
17 changes: 15 additions & 2 deletions core/Controllers/ModeratorEventsController.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using api.core.Data.Enums;
using api.core.Data;
using api.core.Data.Enums;
using api.core.Data.Exceptions;
using api.core.Data.Requests;
using api.core.Data.Responses;
using api.core.Misc;
Expand All @@ -12,7 +14,7 @@ namespace api.core.Controllers;
[ApiController]
[Authorize(Policy = AuthPolicies.IsModerator)]
[Route("api/moderator/events")]
public class ModeratorEventsController(ILogger<ModeratorEventsController> logger, IEventService eventService) : ControllerBase
public class ModeratorEventsController(ILogger<ModeratorEventsController> logger, IEventService eventService, IUserService userService, IReportService reportService) : ControllerBase
{
[HttpPatch("{id}/state")]
public IActionResult UpdateEventState(Guid id, [FromQuery] State newState, [FromQuery] string? reason)
Expand Down Expand Up @@ -46,4 +48,15 @@ public ActionResult<IEnumerable<EventResponseDTO>> GetEventsModerator(

return Ok(response);
}

[HttpGet("reports")]
public ActionResult<IEnumerable<ReportResponseDTO>> GetEventsReports()
{
var reports = reportService.GetReports();

return Ok(new Response<IEnumerable<ReportResponseDTO>>
{
Data = reports,
});
}
}
1 change: 0 additions & 1 deletion core/Controllers/ModeratorUserController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
using api.core.Data.Responses;
using api.core.Misc;
using api.core.services.abstractions;
using api.core.Services.Abstractions;
using api.emails.Models;
using api.emails.Services.Abstractions;

Expand Down
1 change: 0 additions & 1 deletion core/Controllers/UserController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
using api.core.Data.Responses;
using api.core.Misc;
using api.core.services.abstractions;
using api.core.Services.Abstractions;

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
Expand Down
4 changes: 3 additions & 1 deletion core/Data/Entities/Report.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

using api.core.Data.Enums;

using Microsoft.EntityFrameworkCore;

namespace api.core.data.entities;
Expand All @@ -17,7 +19,7 @@ public partial class Report

public string Reason { get; set; } = null!;

public DateTime Date { get; set; }
public ReportCategory Category { get; set; }

public Guid PublicationId { get; set; }

Expand Down
18 changes: 18 additions & 0 deletions core/Data/Enums/ReportCategory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System.Text.Json.Serialization;

namespace api.core.Data.Enums;

/// <summary>
/// 1 - InappropriateContent
/// 2 - FalseInformation
/// 3 - AbusiveBehavior
/// 4 - ObsoleteInformation
/// </summary>
[JsonConverter(typeof(JsonStringEnumConverter))]
public enum ReportCategory
{
InappropriateContent = 1,
FalseInformation = 2,
AbusiveBehavior = 3,
ObsoleteInformation = 4
}
10 changes: 10 additions & 0 deletions core/Data/Requests/ReportRequestDTO.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using api.core.Data.Enums;

namespace api.core.Data.Requests;

public class CreateReportRequestDTO
{
public string Reason { get; set; }

public ReportCategory Category { get; set; }
}
44 changes: 44 additions & 0 deletions core/Data/Responses/ReportResponseDTO.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using api.core.data.entities;
using api.core.Data.Enums;

namespace api.core.Data.Responses;

public class ReportResponseDTO
{
public Guid Id { get; set; }

public string Reason { get; set; }

public ReportCategory Category { get; set; }

public EventResponseDTO Publication { get; set; }

public DateTime CreatedAt { get; set; }

public DateTime UpdatedAt { get; set; }

public static ReportResponseDTO Map(Report report)
{
return new ReportResponseDTO
{
Id = report.Id,
Reason = report.Reason,
Category = report.Category,
CreatedAt = report.CreatedAt,
UpdatedAt = report.UpdatedAt,
Publication = new EventResponseDTO
{
Id = report.Publication.Id,
Title = report.Publication.Title,
Content = report.Publication.Content,
ImageUrl = report.Publication.ImageUrl,
ImageAltText = report.Publication.ImageAltText,
Tags = report.Publication.Tags.Select(TagResponseDTO.Map),
State = report.Publication.State,
PublicationDate = report.Publication.PublicationDate,
CreatedAt = report.Publication.CreatedAt,
UpdatedAt = report.Publication.UpdatedAt,
}
};
}
}
3 changes: 2 additions & 1 deletion core/Extensions/DependencyInjectionExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
using api.core.repositories.abstractions;
using api.core.services.abstractions;
using api.core.Services;
using api.core.Services.Abstractions;
using api.emails.Services;
using api.emails.Services.Abstractions;
using api.files.Services;
Expand All @@ -27,6 +26,7 @@ public static IServiceCollection AddDependencyInjection(this IServiceCollection
services.AddTransient<ITagRepository, TagRepository>();
services.AddTransient<IEventRepository, EventRepository>();
services.AddTransient<IModeratorRepository, ModeratorRepository>();
services.AddTransient<IReportRepository, ReportRepository>();

// Services
services.AddTransient<IUserService, UserService>();
Expand All @@ -35,6 +35,7 @@ public static IServiceCollection AddDependencyInjection(this IServiceCollection
services.AddTransient<IFileShareService, FileShareService>();
services.AddTransient<ITagService, TagService>();
services.AddTransient<IAuthService, AuthService>();
services.AddTransient<IReportService, ReportService>();

return services;
}
Expand Down
31 changes: 31 additions & 0 deletions core/Extensions/RateLimiterExtension.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System.Threading.RateLimiting;

using api.core.controllers;

using Microsoft.AspNetCore.RateLimiting;

namespace api.core.Extensions;

public static class RateLimiterExtension
{
public static IServiceCollection AddRateLimiters(this IServiceCollection services)
{
services.AddRateLimiter(options =>
{
var windowInSeconds = int.Parse(Environment.GetEnvironmentVariable("RATE_LIMIT_TIME_WINDOW_SECONDS") ?? "10");
var permitLimit = int.Parse(Environment.GetEnvironmentVariable("RATE_LIMIT_MAX_REQUESTS") ?? "4");

var window = TimeSpan.FromSeconds(windowInSeconds);

options.AddFixedWindowLimiter(EventsController.RATE_LIMITING_POLICY_NAME, limiterOptions =>
{
limiterOptions.PermitLimit = permitLimit;
limiterOptions.QueueProcessingOrder = QueueProcessingOrder.OldestFirst;
limiterOptions.QueueLimit = 0;
limiterOptions.Window = window;
});
});

return services;
}
}
Loading
Loading