-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
1a4ab13
commit 6cae758
Showing
7 changed files
with
241 additions
and
107 deletions.
There are no files selected for viewing
67 changes: 67 additions & 0 deletions
67
EmailCollector.Api/Controllers/CustomTemplateController.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
using EmailCollector.Api.Authentication; | ||
using EmailCollector.Api.Controllers.RouteConsts; | ||
using EmailCollector.Api.DTOs; | ||
using EmailCollector.Api.Services.CustomEmailTemplates; | ||
using EmailCollector.Domain.Enums; | ||
using Microsoft.AspNetCore.Mvc; | ||
|
||
namespace EmailCollector.Api.Controllers; | ||
|
||
[Route(Routes.CustomTemplatesControllerBase)] | ||
[ApiController] | ||
public class CustomTemplatesController : ControllerBase | ||
{ | ||
private readonly ILogger<CustomTemplatesController> _logger; | ||
private readonly CustomEmailTemplatesService _customEmailTemplatesService; | ||
|
||
public CustomTemplatesController(ILogger<CustomTemplatesController> logger, | ||
CustomEmailTemplatesService customEmailTemplatesService) | ||
{ | ||
_logger = logger; | ||
_customEmailTemplatesService = customEmailTemplatesService; | ||
} | ||
|
||
[HttpGet("{formId:guid}" + Routes.Templates)] | ||
[Produces("application/json")] | ||
[ServiceFilter(typeof(ApiKeyAuthFilter))] | ||
public async Task<IActionResult> GetCustomTemplatesByFormId(Guid formId, [FromQuery] TemplateEvent? templateEvent = null) | ||
{ | ||
_logger.LogInformation($"Getting custom template for form {formId}."); | ||
|
||
return templateEvent == null ? | ||
Ok(await _customEmailTemplatesService.GetCustomEmailTemplatesByFormId(formId)) : | ||
Ok(await _customEmailTemplatesService.GetCustomEmailTemplateByFormIdAndEvent(formId, (TemplateEvent)templateEvent)); | ||
} | ||
|
||
[HttpGet(Routes.Templates + "/{templateId:guid}")] | ||
[Produces("application/json")] | ||
[ServiceFilter(typeof(ApiKeyAuthFilter))] | ||
public async Task<IActionResult> GetCustomTemplatesByTemplateId(Guid templateId) | ||
{ | ||
_logger.LogInformation($"Getting custom template with id {templateId}."); | ||
|
||
return Ok(await _customEmailTemplatesService.GetCustomEmailTemplateById(templateId)); | ||
} | ||
|
||
[HttpPost(Routes.Templates)] | ||
[Produces("application/json")] | ||
[ServiceFilter(typeof(ApiKeyAuthFilter))] | ||
public async Task<ActionResult> PostCustomTemplate(CustomEmailTemplateDto templateDto) | ||
{ | ||
_logger.LogInformation("Creating custom template."); | ||
|
||
var templateId = await _customEmailTemplatesService.SaveCustomEmailTemplate(templateDto); | ||
return CreatedAtAction("GetCustomTemplatesByTemplateId", new { id = templateId }, templateDto); | ||
} | ||
|
||
[HttpDelete(Routes.Templates + "/{templateId:guid}")] | ||
[Produces("application/json")] | ||
[ServiceFilter(typeof(ApiKeyAuthFilter))] | ||
public async Task<ActionResult> DeleteCustomTemplate(Guid templateId) | ||
{ | ||
_logger.LogInformation("Creating custom template."); | ||
|
||
await _customEmailTemplatesService.DeleteCustomEmailTemplate(templateId); | ||
return Ok(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
using System.Security.Claims; | ||
using EmailCollector.Api.Authentication; | ||
using EmailCollector.Api.Controllers.RouteConsts; | ||
using EmailCollector.Api.Services; | ||
using EmailCollector.Api.Services.Exports; | ||
using Microsoft.AspNetCore.Mvc; | ||
|
||
namespace EmailCollector.Api.Controllers; | ||
|
||
[Route(Routes.ExportsControllerBase)] | ||
public class ExportsController : ControllerBase | ||
{ | ||
private readonly IFormService _formService; | ||
private readonly ILogger<ExportsController> _logger; | ||
|
||
public ExportsController(IFormService formService, ILogger<ExportsController> logger) | ||
{ | ||
_formService = formService; | ||
_logger = logger; | ||
} | ||
|
||
/// <summary> | ||
/// Export all user's forms. | ||
/// </summary> | ||
/// <param name="exportFormat">export format</param> | ||
/// <returns>file containing the exported data</returns> | ||
/// <exception cref="ArgumentException"></exception> | ||
[HttpGet(Routes.Export)] | ||
[ServiceFilter(typeof(ApiKeyAuthFilter))] | ||
public async Task<IActionResult> ExportForms([FromQuery] ExportFormat exportFormat = ExportFormat.Csv) | ||
{ | ||
_logger.LogInformation($"Exporting forms."); | ||
var userIdClaim = User.FindFirst(ClaimTypes.NameIdentifier)?.Value; | ||
if (string.IsNullOrEmpty(userIdClaim) || !Guid.TryParse(userIdClaim, out var userId)) | ||
{ | ||
return Unauthorized("Invalid or missing user identifier"); | ||
} | ||
var forms = await _formService.GetFormsByUserAsync(userId); | ||
var formIds = forms.Select(f => f.Id).ToList(); | ||
|
||
var fileBytes = await _formService.ExportFormsAsync(formIds, exportFormat); | ||
if (fileBytes == null || fileBytes.Length == 0) | ||
{ | ||
_logger.LogInformation("No forms were available for export or result was empty."); | ||
return NotFound("No forms found to export."); | ||
} | ||
|
||
const string contentType = "application/octet-stream"; | ||
var fileName = exportFormat switch | ||
{ | ||
ExportFormat.Csv => "collecto_export.csv", | ||
ExportFormat.Json => "collecto_export.xlsx", | ||
// should not get there, since ExportFormat is type validated OOTB. | ||
_ => throw new ArgumentException("Unsupported export format") | ||
}; | ||
|
||
return File(fileBytes, contentType, fileName); | ||
} | ||
|
||
/// <summary> | ||
/// Exports a single form. | ||
/// </summary> | ||
/// <param name="formId">form to export</param> | ||
/// <param name="exportFormat">export format</param> | ||
/// <returns>file containing the exported data</returns> | ||
/// <exception cref="ArgumentException"></exception> | ||
[HttpGet("{formId:guid}" + Routes.Export)] | ||
[ServiceFilter(typeof(ApiKeyAuthFilter))] | ||
public async Task<IActionResult> ExportForm(Guid formId, [FromQuery] ExportFormat exportFormat = ExportFormat.Csv) | ||
{ | ||
_logger.LogInformation($"Exporting form {formId}."); | ||
|
||
var fileBytes = await _formService.ExportFormsAsync([formId], exportFormat); | ||
if (fileBytes == null || fileBytes.Length == 0) | ||
{ | ||
_logger.LogInformation("No forms were available for export or result was empty."); | ||
return NotFound("No forms found to export."); | ||
} | ||
|
||
const string contentType = "application/octet-stream"; | ||
var fileName = exportFormat switch | ||
{ | ||
ExportFormat.Csv => "collecto_export.csv", | ||
ExportFormat.Json => "collecto_export.xlsx", | ||
// should not get there, since ExportFormat is type validated OOTB. | ||
_ => throw new ArgumentException("Unsupported export format") | ||
}; | ||
|
||
return File(fileBytes, contentType, fileName); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
using EmailCollector.Domain.Entities; | ||
|
||
namespace EmailCollector.Api.Controllers.RouteConsts; | ||
|
||
public class Routes | ||
{ | ||
/* -------- Base routes -------- */ | ||
private const string Base = "/api"; | ||
private const string ExportsBase = "/export"; | ||
private const string FormsBase = "/forms"; | ||
private const string EmailSignupsBase = "/submissions"; | ||
|
||
/* -------- Signup forms routes -------- */ | ||
/// <summary> | ||
/// <see cref="SignupFormsController"/> | ||
/// </summary> | ||
public const string SignupFormsControllerBase = Base + FormsBase; | ||
public const string GetSubmissions = "/submissions"; | ||
public const string Export = "/export"; | ||
|
||
/* -------- Exports routes -------- */ | ||
/// <summary> | ||
/// Export is a action performed on <see cref="SignupForm"/> | ||
/// hence we use the same base route as <see cref="SignupFormsControllerBase"/> | ||
/// <see cref="ExportsController"/> | ||
/// </summary> | ||
public const string ExportsControllerBase = Base + FormsBase; | ||
|
||
/* -------- EmailSignups routes -------- */ | ||
public const string EmailSignupsControllerBase = Base + EmailSignupsBase; | ||
public const string Confirmations = "/confirmations"; | ||
|
||
/* -------- CustomTemplates routes -------- */ | ||
/// <summary> | ||
/// <see cref="CustomEmailTemplate"/> is a sub-entity of <see cref="SignupForm"/> | ||
/// hence we use the same base route as <see cref="SignupFormsControllerBase"/> | ||
/// </summary> | ||
public const string CustomTemplatesControllerBase = Base + FormsBase; | ||
public const string Templates = "/templates"; | ||
} |
Oops, something went wrong.