Files
DiunaBI/DiunaBI.API/Controllers/DataInboxController.cs

202 lines
6.8 KiB
C#
Raw Normal View History

2025-11-18 20:38:35 +01:00
using System.Text;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using DiunaBI.Infrastructure.Data;
using DiunaBI.Domain.Entities;
2025-12-01 12:55:47 +01:00
using DiunaBI.Application.DTOModels;
using DiunaBI.Application.DTOModels.Common;
2025-11-18 20:38:35 +01:00
namespace DiunaBI.API.Controllers;
2025-12-01 17:56:17 +01:00
[Authorize]
2025-11-18 20:38:35 +01:00
[ApiController]
[Route("[controller]")]
public class DataInboxController : Controller
{
private readonly AppDbContext _db;
private readonly IConfiguration _configuration;
private readonly ILogger<DataInboxController> _logger;
public DataInboxController(
AppDbContext db,
IConfiguration configuration,
ILogger<DataInboxController> logger)
{
_db = db;
_configuration = configuration;
_logger = logger;
}
[HttpPut]
[Route("Add/{apiKey}")]
[AllowAnonymous]
public IActionResult Add(string apiKey, [FromBody] DataInbox dataInbox)
{
if (apiKey != _configuration["apiKey"])
{
_logger.LogWarning("DataInbox: Unauthorized request - wrong apiKey for source {Source}", dataInbox.Source);
return Unauthorized();
}
try
{
if (!Request.Headers.TryGetValue("Authorization", out var authHeader))
{
_logger.LogWarning("DataInbox: Unauthorized request - no authorization header for source {Source}", dataInbox.Source);
return Unauthorized();
}
var credentialsArr = authHeader.ToString().Split(" ");
if (credentialsArr.Length != 2)
{
_logger.LogWarning("DataInbox: Unauthorized request - wrong auth header format for source {Source}", dataInbox.Source);
return Unauthorized();
}
var authValue = Encoding.UTF8.GetString(Convert.FromBase64String(credentialsArr[1]));
var username = authValue.Split(':')[0];
var password = authValue.Split(':')[1];
2025-11-27 11:07:23 +01:00
if (username != _configuration["apiUser"] || password != _configuration["apiPass"])
2025-11-18 20:38:35 +01:00
{
_logger.LogWarning("DataInbox: Unauthorized request - bad credentials for source {Source}", dataInbox.Source);
return Unauthorized();
}
// check if datainbox.data is base64 encoded value
if (!string.IsNullOrEmpty(dataInbox.Data) && !IsBase64String(dataInbox.Data))
{
_logger.LogWarning("DataInbox: Invalid data format - not base64 encoded for source {Source}", dataInbox.Source);
return BadRequest("Invalid data format - not base64 encoded");
}
dataInbox.Id = Guid.NewGuid();
dataInbox.CreatedAt = DateTime.UtcNow;
_db.DataInbox.Add(dataInbox);
_db.SaveChanges();
_logger.LogInformation("DataInbox: Insert success for source {Source}, name {Name}", dataInbox.Source, dataInbox.Name);
if (dataInbox.Name == "morska.d3.importer")
{
_logger.LogDebug("DataInbox: Detected morska.d3.importer - processing will be handled by AutoImport");
}
return Ok();
}
catch (Exception e)
{
_logger.LogError(e, "DataInbox: Insert error for source {Source}, name {Name}", dataInbox.Source, dataInbox.Name);
return BadRequest("An error occurred processing your request");
2025-11-18 20:38:35 +01:00
}
}
[HttpGet]
2025-12-01 12:55:47 +01:00
[Route("GetAll")]
2025-12-01 13:21:45 +01:00
public IActionResult GetAll([FromQuery] int start, [FromQuery] int limit, [FromQuery] string? search)
2025-11-18 20:38:35 +01:00
{
try
{
2025-12-01 12:55:47 +01:00
var query = _db.DataInbox.AsQueryable();
2025-12-01 13:21:45 +01:00
if (!string.IsNullOrEmpty(search))
2025-12-01 12:55:47 +01:00
{
2025-12-01 13:21:45 +01:00
query = query.Where(x => x.Name.Contains(search) || x.Source.Contains(search));
2025-12-01 12:55:47 +01:00
}
var totalCount = query.Count();
var items = query
.OrderByDescending(x => x.CreatedAt)
.Skip(start)
.Take(limit)
.AsNoTracking()
.Select(x => new DataInboxDto
{
Id = x.Id,
Name = x.Name,
Source = x.Source,
Data = x.Data,
CreatedAt = x.CreatedAt
})
.ToList();
var pagedResult = new PagedResult<DataInboxDto>
{
Items = items,
TotalCount = totalCount,
Page = (start / limit) + 1,
PageSize = limit
};
2025-12-01 13:21:45 +01:00
_logger.LogDebug("GetAll: Retrieved {Count} of {TotalCount} data inbox items (page {Page}) with filter search={Search}",
items.Count, totalCount, pagedResult.Page, search);
2025-12-01 12:55:47 +01:00
return Ok(pagedResult);
}
catch (Exception e)
{
_logger.LogError(e, "GetAll: Error retrieving data inbox items");
return BadRequest("An error occurred processing your request");
2025-12-01 12:55:47 +01:00
}
}
[HttpGet]
[Route("{id:guid}")]
public IActionResult Get(Guid id)
{
try
{
var dataInbox = _db.DataInbox
.AsNoTracking()
.FirstOrDefault(x => x.Id == id);
if (dataInbox == null)
{
_logger.LogWarning("Get: Data inbox item {Id} not found", id);
return NotFound();
}
var dto = new DataInboxDto
{
Id = dataInbox.Id,
Name = dataInbox.Name,
Source = dataInbox.Source,
Data = dataInbox.Data,
CreatedAt = dataInbox.CreatedAt
};
_logger.LogDebug("Get: Retrieved data inbox item {Id} {Name}", id, dataInbox.Name);
return Ok(dto);
2025-11-18 20:38:35 +01:00
}
catch (Exception e)
{
2025-12-01 12:55:47 +01:00
_logger.LogError(e, "Get: Error retrieving data inbox item {Id}", id);
return BadRequest("An error occurred processing your request");
2025-11-18 20:38:35 +01:00
}
}
// helpers
private bool IsBase64String(string data)
{
if (string.IsNullOrEmpty(data))
{
return false;
}
try
{
var base64Bytes = Convert.FromBase64String(data);
var utf8String = Encoding.UTF8.GetString(base64Bytes);
var reEncoded = Convert.ToBase64String(Encoding.UTF8.GetBytes(utf8String));
return data.TrimEnd('=') == reEncoded.TrimEnd('=');
}
catch (FormatException)
{
return false;
}
catch (DecoderFallbackException)
{
return false;
}
}
}