diff --git a/backend/API/API.csproj b/backend/API/API.csproj
index 5c6b3b0..59e8b4c 100644
--- a/backend/API/API.csproj
+++ b/backend/API/API.csproj
@@ -10,10 +10,6 @@
-
-
-
-
diff --git a/backend/API/Controllers/BaseController.cs b/backend/API/Controllers/BaseController.cs
index 32d2a7c..2587bc2 100644
--- a/backend/API/Controllers/BaseController.cs
+++ b/backend/API/Controllers/BaseController.cs
@@ -1,10 +1,9 @@
using Microsoft.AspNetCore.Mvc;
-namespace HealthcareManager.API.Controllers
+namespace HealthcareManager.API.Controllers;
+
+[Route("api/v1/[controller]")]
+[ApiController]
+public abstract class BaseApiController : ControllerBase
{
- [Route("api/v1/[controller]")]
- [ApiController]
- public abstract class BaseApiController : ControllerBase
- {
- }
}
\ No newline at end of file
diff --git a/backend/API/Controllers/ChatController.cs b/backend/API/Controllers/ChatController.cs
index fcf543e..f9d3256 100644
--- a/backend/API/Controllers/ChatController.cs
+++ b/backend/API/Controllers/ChatController.cs
@@ -1,16 +1,14 @@
using Infrastructure.Services.MongoDB;
-using Microsoft.AspNetCore.Mvc;
-namespace HealthcareManager.API.Controllers
+namespace HealthcareManager.API.Controllers;
+
+public class ChatController : BaseApiController
{
- public class ChatController : BaseApiController
+ private readonly MongoDbService _mongoDbService;
+
+ public ChatController(MongoDbService mongoDbService)
{
- private readonly MongoDbService _mongoDbService;
-
- public ChatController(MongoDbService mongoDbService)
- {
- _mongoDbService = mongoDbService;
- }
-
+ _mongoDbService = mongoDbService;
}
+
}
diff --git a/backend/API/Controllers/DoctorsController.cs b/backend/API/Controllers/DoctorsController.cs
index 9d3d60a..62a3874 100644
--- a/backend/API/Controllers/DoctorsController.cs
+++ b/backend/API/Controllers/DoctorsController.cs
@@ -2,50 +2,116 @@
using Core.Entities;
using Application.Endpoints.Doctors.Login;
using Application.Services.Database;
+using Application.Endpoints.Doctors.Registration;
+using Application.Endpoints.Doctors.ResetPassword;
+using Application.Endpoints.Doctors.Profile;
-namespace HealthcareManager.API.Controllers
+namespace HealthcareManager.API.Controllers;
+
+[ApiController]
+[Route("api/[controller]")]
+public class DoctorsController : ControllerBase
{
- [ApiController]
- [Route("api/[controller]")]
- public class DoctorsController : ControllerBase
+ private readonly IDoctorRepository _database;
+
+ public DoctorsController(IDoctorRepository database)
{
- private readonly IDoctorRepository _database;
+ _database = database ?? throw new ArgumentNullException(nameof(database));
+ }
- public DoctorsController(IDoctorRepository database)
+ [HttpGet]
+ public async Task> GetAllDoctors()
+ {
+ var handler = new DoctorProfileHandler(_database);
+ var response = await handler.HandleGetAll();
+ if (!response.Success)
{
- _database = database ?? throw new ArgumentNullException(nameof(database));
+ return BadRequest(response);
}
- [HttpGet("{id}")]
- public async Task> GetDoctor(int id)
+ return Ok(response.Data);
+ }
+
+ [HttpGet("{id}")]
+ public async Task> GetDoctor(Guid id)
+ {
+ var handler = new DoctorProfileHandler(_database);
+ var response = await handler.HandleGet(id);
+ if (!response.Success)
{
- return NotFound();
+ return BadRequest(response);
}
- [HttpPost]
- public async Task> Login(DoctorLoginDTO doctor)
+ return Ok(response.Data);
+ }
+
+ [HttpPost("login")]
+ public async Task> Login(DoctorLoginDTO doctor)
+ {
+ var handler = new DoctorLoginHandler(_database);
+ var response = await handler.Handle(doctor).ConfigureAwait(false);
+
+ if(!response.Success)
{
- var handler = new DoctorLoginHandler(_database);
- var response = handler.Handle(doctor).Result;
+ return Unauthorized(response);
+ }
- if(!response.Success)
- {
- return Unauthorized(response);
- }
+ return Ok(response);
+ }
+ [HttpPost("register")]
+ public async Task> Register(DoctorRegistrationDto doctor)
+ {
+ var handler = new DoctorRegistrationHandler(_database);
+ var response = await handler.Handle(doctor).ConfigureAwait(false);
+
+ if (!response.Success)
+ {
+ return Unauthorized(response);
+ }
+
+ return Ok(response);
+ }
+
+ [HttpPost("resetPassword")]
+ public async Task ResetPassword(DoctorLoginDTO resetDoctorDto)
+ {
+ var handler = new DoctorResetPasswordHandler(_database);
+ var response = await handler.Handle(resetDoctorDto).ConfigureAwait(false);
+
+ if (response.Success)
+ {
return Ok(response);
}
- [HttpPut("{id}")]
- public async Task PutDoctor(int id, Doctor doctor)
+ return BadRequest(response);
+ }
+
+ [HttpPut("{id}/profile")]
+ public async Task UpdateDoctorProfile(Guid id, [FromBody]DoctorProfileDTO doctorDto)
+ {
+ var handler = new DoctorProfileHandler(_database);
+ var response = await handler.HandleUpdate(id, doctorDto).ConfigureAwait(false);
+
+ if (response.Success)
{
- return NotFound();
+ return Ok(response);
}
- [HttpDelete("{id}")]
- public async Task DeleteDoctor(int id)
+ return BadRequest(response);
+ }
+
+ [HttpDelete("{id}/profile")]
+ public async Task DeleteDoctorProfile(Guid id)
+ {
+ var handler = new DoctorProfileHandler(_database);
+ var response = await handler.HandleDelete(id).ConfigureAwait(false);
+
+ if (response.Success)
{
- return NotFound();
+ return NoContent();
}
+
+ return BadRequest(response);
}
}
diff --git a/backend/API/Controllers/MedicalHistoryController.cs b/backend/API/Controllers/MedicalHistoryController.cs
index cb5bc22..e124c24 100644
--- a/backend/API/Controllers/MedicalHistoryController.cs
+++ b/backend/API/Controllers/MedicalHistoryController.cs
@@ -1,9 +1,67 @@
-using Microsoft.AspNetCore.Mvc;
+using Application.Endpoints.MedicalHistories;
+using Application.Services.Database;
+using Core.Entities;
+using Microsoft.AspNetCore.Mvc;
-namespace HealthcareManager.API.Controllers
+namespace HealthcareManager.API.Controllers;
+
+[ApiController]
+[Route("api/[controller]")]
+public class MedicalHistoryController : ControllerBase
{
- public class MedicalHistoryController : BaseApiController
- {
+ private readonly IMedicalHistoryRepository _medicalHistoryRepository;
+ private readonly IPacientRepository _pacientRepository;
+ public MedicalHistoryController(IMedicalHistoryRepository medicalHistoryRepository, IPacientRepository pacientRepository)
+ {
+ _medicalHistoryRepository = medicalHistoryRepository ?? throw new ArgumentNullException(nameof(medicalHistoryRepository));
+ _pacientRepository = pacientRepository ?? throw new ArgumentNullException(nameof(pacientRepository));
+ }
+
+ [HttpGet("{id}")]
+ public async Task> GetAsync(Guid id)
+ {
+ var handler = new MedicalHistoryHandler(_medicalHistoryRepository, _pacientRepository);
+ var response = await handler.HandleGet(id);
+ if (!response.Success)
+ {
+ return BadRequest(response);
+ }
+
+ return Ok(response.Data);
+ }
+
+ [HttpPost("{id}")]
+ public async Task> PostAsync(Guid id, [FromBody] byte[] description)
+ {
+ var handler = new MedicalHistoryHandler(_medicalHistoryRepository, _pacientRepository);
+ var response = await handler.HandleCreate(id, description).ConfigureAwait(false);
+
+ if (!response.Success)
+ {
+ return Unauthorized(response);
+ }
+
+ return Ok(response);
+ }
+
+ [HttpPut("{id}")]
+ public async Task UpdateAsync(Guid id, [FromBody] MedicalHistoryDTO medicalHistoryDTO)
+ {
+ var handler = new MedicalHistoryHandler(_medicalHistoryRepository, _pacientRepository);
+ var response = await handler.HandleUpdate(id, medicalHistoryDTO).ConfigureAwait(false);
+
+ if (response.Success)
+ {
+ return Ok(response);
+ }
+
+ return BadRequest(response);
+ }
+
+ [HttpPut("grant_access")]
+ public async Task GrantAccessToMedicalHistory(Guid id)
+ {
+ return NotFound();
}
}
diff --git a/backend/API/Controllers/PacientsController.cs b/backend/API/Controllers/PacientsController.cs
index fb0113c..2ec98b4 100644
--- a/backend/API/Controllers/PacientsController.cs
+++ b/backend/API/Controllers/PacientsController.cs
@@ -1,9 +1,117 @@
using Microsoft.AspNetCore.Mvc;
+using Core.Entities;
+using Application.Endpoints.Pacients.Login;
+using Application.Services.Database;
+using Application.Endpoints.Pacients.Registration;
+using Application.Endpoints.Pacients.ResetPassword;
+using Application.Endpoints.Pacients.Profile;
-namespace HealthcareManager.API.Controllers
+namespace HealthcareManager.API.Controllers;
+
+[ApiController]
+[Route("api/[controller]")]
+public class PacientsController : ControllerBase
{
- public class PacientsController : BaseApiController
+ private readonly IPacientRepository _database;
+
+ public PacientsController(IPacientRepository database)
{
-
+ _database = database ?? throw new ArgumentNullException(nameof(database));
+ }
+
+ [HttpGet]
+ public async Task> GetAllPacients()
+ {
+ var handler = new PacientProfileHandler(_database);
+ var response = await handler.HandleGetAll();
+ if (!response.Success)
+ {
+ return BadRequest(response);
+ }
+
+ return Ok(response.Data);
+ }
+
+ [HttpGet("{id}")]
+ public async Task> GetPacient(Guid id)
+ {
+ var handler = new PacientProfileHandler(_database);
+ var response = await handler.HandleGet(id);
+ if (!response.Success)
+ {
+ return BadRequest(response);
+ }
+
+ return Ok(response.Data);
+ }
+
+ [HttpPost("login")]
+ public async Task> Login(PacientLoginDTO pacient)
+ {
+ var handler = new PacientLoginHandler(_database);
+ var response = await handler.Handle(pacient).ConfigureAwait(false);
+
+ if (!response.Success)
+ {
+ return Unauthorized(response);
+ }
+
+ return Ok(response);
+ }
+
+ [HttpPost("register")]
+ public async Task> Register(PacientRegistrationDto pacient)
+ {
+ var handler = new PacientRegistrationHandler(_database);
+ var response = await handler.Handle(pacient).ConfigureAwait(false);
+
+ if (!response.Success)
+ {
+ return Unauthorized(response);
+ }
+
+ return Ok(response);
+ }
+
+ [HttpPost("resetPassword")]
+ public async Task ResetPassword(PacientLoginDTO resetPacientDto)
+ {
+ var handler = new PacientResetPasswordHandler(_database);
+ var response = await handler.Handle(resetPacientDto).ConfigureAwait(false);
+
+ if (response.Success)
+ {
+ return Ok(response);
+ }
+
+ return BadRequest(response);
+ }
+
+ [HttpPut("{id}/profile")]
+ public async Task UpdatePacientProfile(Guid id, [FromBody] PacientProfileDTO pacientDto)
+ {
+ var handler = new PacientProfileHandler(_database);
+ var response = await handler.HandleUpdate(id, pacientDto).ConfigureAwait(false);
+
+ if (response.Success)
+ {
+ return Ok(response);
+ }
+
+ return BadRequest(response);
+ }
+
+ [HttpDelete("{id}/profile")]
+ public async Task DeletePacientProfile(Guid id)
+ {
+ var handler = new PacientProfileHandler(_database);
+ var response = await handler.HandleDelete(id).ConfigureAwait(false);
+
+ if (response.Success)
+ {
+ return NoContent();
+ }
+
+ return BadRequest(response);
}
}
diff --git a/backend/API/Middlewares/ApiKeyValidationMiddleware.cs b/backend/API/Middlewares/ApiKeyValidationMiddleware.cs
new file mode 100644
index 0000000..142ea4c
--- /dev/null
+++ b/backend/API/Middlewares/ApiKeyValidationMiddleware.cs
@@ -0,0 +1,42 @@
+namespace API.Middlewares;
+
+public class ApiKeyValidationMiddleware
+{
+ private readonly RequestDelegate _next;
+ private const string APIKEYNAME = "ApiKey";
+
+ public ApiKeyValidationMiddleware(RequestDelegate next)
+ {
+ _next = next;
+ }
+
+ public async Task InvokeAsync(HttpContext context)
+ {
+ if (!context.Request.Headers.TryGetValue(APIKEYNAME, out var extractedApiKey))
+ {
+ context.Response.StatusCode = 401;
+ await context.Response.WriteAsync("API Key was not provided.");
+ return;
+ }
+
+ var appSettings = context.RequestServices.GetRequiredService();
+
+ var apiKey = appSettings.GetValue("ApiKey");
+
+ if (string.IsNullOrEmpty(apiKey))
+ {
+ context.Response.StatusCode = 400;
+ await context.Response.WriteAsync("Unable to retrieve API key.");
+ return;
+ }
+
+ if (!apiKey.Equals(extractedApiKey))
+ {
+ context.Response.StatusCode = 401;
+ await context.Response.WriteAsync("Unauthorized client.");
+ return;
+ }
+
+ await _next(context);
+ }
+}
diff --git a/backend/API/Middlewares/BodyCheckMiddleware.cs b/backend/API/Middlewares/BodyCheckMiddleware.cs
new file mode 100644
index 0000000..557290d
--- /dev/null
+++ b/backend/API/Middlewares/BodyCheckMiddleware.cs
@@ -0,0 +1,35 @@
+using System.Net;
+using System.Text;
+
+namespace API.Middlewares;
+
+public class BodyCheckMiddleware(RequestDelegate next)
+{
+ private readonly RequestDelegate _next = next;
+
+ public async Task InvokeAsync(HttpContext context)
+ {
+ // Only check the body for POST and PUT requests
+ if (context.Request.Method == HttpMethods.Post || context.Request.Method == HttpMethods.Put)
+ {
+ // Enable buffering so we can read the stream without issues downstream
+ context.Request.EnableBuffering();
+
+ var buffer = new byte[Convert.ToInt32(context.Request.ContentLength)];
+ await context.Request.Body.ReadAsync(buffer, 0, buffer.Length);
+ string requestBody = Encoding.UTF8.GetString(buffer);
+ context.Request.Body.Seek(0, SeekOrigin.Begin); // Reset the stream for next middleware
+
+ // Check if the body is empty
+ if (string.IsNullOrEmpty(requestBody))
+ {
+ context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
+ await context.Response.WriteAsync("Request body cannot be empty.");
+ return;
+ }
+ }
+
+ await _next(context);
+ }
+}
+
diff --git a/backend/API/Program.cs b/backend/API/Program.cs
index 1177da2..db3649c 100644
--- a/backend/API/Program.cs
+++ b/backend/API/Program.cs
@@ -1,7 +1,8 @@
+using API.Middlewares;
using Infrastructure;
using Infrastructure.Data;
using Microsoft.EntityFrameworkCore;
-using Microsoft.Extensions.DependencyInjection;
+using Microsoft.OpenApi.Models;
var builder = WebApplication.CreateBuilder(args);
@@ -9,7 +10,31 @@ builder.Services.AddControllers();
builder.Services.AddInfrastructureServices(builder.Configuration);
builder.Services.AddEndpointsApiExplorer();
-builder.Services.AddSwaggerGen();
+builder.Services.AddSwaggerGen(c =>
+{
+ c.AddSecurityDefinition("ApiKey", new OpenApiSecurityScheme
+ {
+ Description = "ApiKey must appear in header",
+ Type = SecuritySchemeType.ApiKey,
+ Name = "ApiKey",
+ In = ParameterLocation.Header,
+ Scheme = "ApiKeyScheme"
+ });
+ var key = new OpenApiSecurityScheme()
+ {
+ Reference = new OpenApiReference
+ {
+ Type = ReferenceType.SecurityScheme,
+ Id = "ApiKey"
+ },
+ In = ParameterLocation.Header
+ };
+ var requirement = new OpenApiSecurityRequirement
+ {
+ { key, new List() }
+ };
+ c.AddSecurityRequirement(requirement);
+});
var app = builder.Build();
@@ -25,6 +50,10 @@ app.UseAuthorization();
app.MapControllers();
+// Middlewares
+app.UseMiddleware();
+app.UseMiddleware();
+
using (var scope = app.Services.CreateScope())
{
var services = scope.ServiceProvider;
diff --git a/backend/API/appsettings.json b/backend/API/appsettings.json
index 292fe14..b3317b4 100644
--- a/backend/API/appsettings.json
+++ b/backend/API/appsettings.json
@@ -10,5 +10,6 @@
"MongoDBDatabase": "mongodb+srv://andrei_cerbu:andrei_cerbu@cluster0.v80skg6.mongodb.net/?retryWrites=true&w=majority&appName=Cluster0"
},
- "AllowedHosts": "*"
+ "AllowedHosts": "*",
+ "ApiKey": "testapikey"
}
diff --git a/backend/Application/Application.csproj b/backend/Application/Application.csproj
index f31b960..31564e9 100644
--- a/backend/Application/Application.csproj
+++ b/backend/Application/Application.csproj
@@ -10,4 +10,8 @@
+
+
+
+