From 692fc4f29043f022790de63476aaa63e214c6734 Mon Sep 17 00:00:00 2001
From: DeepnaPooja
Date: Wed, 2 Sep 2026 15:19:46 +0530
Subject: [PATCH 01/61] fix the ride create issue
---
Distribution/Features/Ride/RideController.cs | 2 +-
Distribution/Features/Ride/RideDTOs.cs | 10 +-
Distribution/Features/Ride/RideService.cs | 10 +-
.../Middleware/AuthMiddleware.cs | 185 -----------------
.../Authorization/Middleware/JwtMiddleware.cs | 191 ------------------
Distribution/docs/testbug.md | 10 +-
6 files changed, 19 insertions(+), 389 deletions(-)
delete mode 100644 Distribution/Infra/Authorization/Middleware/AuthMiddleware.cs
delete mode 100644 Distribution/Infra/Authorization/Middleware/JwtMiddleware.cs
diff --git a/Distribution/Features/Ride/RideController.cs b/Distribution/Features/Ride/RideController.cs
index f936c39..008d8ee 100644
--- a/Distribution/Features/Ride/RideController.cs
+++ b/Distribution/Features/Ride/RideController.cs
@@ -40,7 +40,7 @@ public class RideController(RideService service, ICurrentUserService currentUser
{
try
{
- var result = await service.AssignDriverAsync(id, request.FK_DriverProfileId, ct);
+ var result = await service.AssignDriverAsync(id, request.DriverProfileId, ct);
return Ok(result);
}
catch (KeyNotFoundException) { return NotFound(); }
diff --git a/Distribution/Features/Ride/RideDTOs.cs b/Distribution/Features/Ride/RideDTOs.cs
index ab1f25d..d43b3c3 100644
--- a/Distribution/Features/Ride/RideDTOs.cs
+++ b/Distribution/Features/Ride/RideDTOs.cs
@@ -25,12 +25,12 @@ public record RideResponse(
public record CreateRideRequest(
RideType RideType,
- Guid FK_VehicleId,
- Guid FK_DriverProfileId,
- Guid FK_RouteId,
- Guid? FK_SourceWarehouseId);
+ Guid VehicleId,
+ Guid DriverProfileId,
+ Guid RouteId,
+ Guid? SourceWarehouseId);
-public record AssignRideDriverRequest(Guid FK_DriverProfileId);
+public record AssignRideDriverRequest(Guid DriverProfileId);
public record ActivateRideRequest(int Meterstart);
diff --git a/Distribution/Features/Ride/RideService.cs b/Distribution/Features/Ride/RideService.cs
index df20d44..384b860 100644
--- a/Distribution/Features/Ride/RideService.cs
+++ b/Distribution/Features/Ride/RideService.cs
@@ -36,19 +36,19 @@ public class RideService(
public async Task CreateAsync(CreateRideRequest request, CancellationToken ct = default)
{
- var vehicle = await vehicleRepo.GetByIdAsync(request.FK_VehicleId)
+ var vehicle = await vehicleRepo.GetByIdAsync(request.VehicleId)
?? throw new InvalidOperationException("Vehicle not found");
- var sourceWarehouseId = vehicle.DefaultWarehouseId ?? request.FK_SourceWarehouseId;
+ var sourceWarehouseId = vehicle.DefaultWarehouseId ?? request.SourceWarehouseId;
if (!sourceWarehouseId.HasValue)
throw new InvalidOperationException("Source warehouse is required for this vehicle");
var ride = new DeliveryRun
{
RideType = request.RideType,
- FK_VehicleId = request.FK_VehicleId,
- FK_DriverProfileId = request.FK_DriverProfileId,
- FK_RouteId = request.FK_RouteId,
+ FK_VehicleId = request.VehicleId,
+ FK_DriverProfileId = request.DriverProfileId,
+ FK_RouteId = request.RouteId,
FK_SourceWarehouseId = sourceWarehouseId.Value,
Status = RideStatus.Draft
};
diff --git a/Distribution/Infra/Authorization/Middleware/AuthMiddleware.cs b/Distribution/Infra/Authorization/Middleware/AuthMiddleware.cs
deleted file mode 100644
index 0715e3f..0000000
--- a/Distribution/Infra/Authorization/Middleware/AuthMiddleware.cs
+++ /dev/null
@@ -1,185 +0,0 @@
-using System.IdentityModel.Tokens.Jwt;
-using System.Security.Claims;
-using System.Security.Cryptography;
-using Distribution.Features.User;
-using Distribution.Infra.Authorization;
-using Microsoft.IdentityModel.Tokens;
-
-namespace Distribution.Infra.Authorization.Middleware;
-
-///
-/// Ported from OSMCore's System/Authentication/AuthMiddleware.cs (global path-skip-based
-/// middleware). NOT registered in Program.cs — this project's actual token validation is the
-/// standard AddJwtBearer handler (see Program.cs), same as OSMCore's own recommendation. Kept here
-/// unregistered, exactly like OSMCore's own copy, for reference/reuse if a project needs a
-/// middleware-based (rather than AddJwtBearer-based) validation entry point.
-///
-/// Two adaptations from the OSMCore original, both required for this to actually work against
-/// this project's authorization system rather than just compiling:
-/// 1. RSA key parsing goes through instead of RSA.FromXmlString,
-/// which is Windows-only in modern .NET (see docs/authentication_flow.md §2.2 Gotcha).
-/// 2. After validating the token, the user id is mapped onto a local User/Role row and
-/// role_id/role_level/username claims are attached — the same step Program.cs's
-/// OnTokenValidated performs for the AddJwtBearer path. Without this, a request authenticated
-/// through this middleware would have no role_id claim, and every
-/// [Authorize(Policy = "resource.action")] check (PermissionAuthorizationHandler) would fail.
-///
-public sealed class AuthMiddleware(RequestDelegate next, IConfiguration configuration, ILogger logger)
-{
- public async Task InvokeAsync(HttpContext context)
- {
- if (ShouldSkipAuthentication(context.Request.Path))
- {
- await next(context);
- return;
- }
-
- if (!TryGetToken(context, out var token))
- {
- await RejectAsync(context, "Authentication token is missing.");
- return;
- }
-
- try
- {
- var principal = ValidateToken(token);
- var userRepo = context.RequestServices.GetRequiredService();
- if (!await TryAttachLocalRoleClaimsAsync(principal, userRepo))
- {
- await RejectAsync(context, "User not found or inactive.");
- return;
- }
-
- context.User = principal;
- PopulateContextItems(context, principal);
- await next(context);
- }
- catch (Exception ex) when (ex is SecurityTokenException or ArgumentException or CryptographicException)
- {
- logger.LogInformation(ex, "JWT validation failed for request path {Path}", context.Request.Path);
- await RejectAsync(context, "Invalid or expired token.");
- }
- }
-
- private ClaimsPrincipal ValidateToken(string token)
- {
- var jwtOptions = configuration.GetSection("Jwt").Get()
- ?? throw new InvalidOperationException("Jwt configuration is missing.");
-
- if (string.IsNullOrWhiteSpace(jwtOptions.PublicKey))
- {
- throw new InvalidOperationException("Jwt:PublicKey configuration is missing.");
- }
-
- using var rsa = RsaXmlKeyReader.ReadPublicKey(jwtOptions.PublicKey);
-
- var handler = new JwtSecurityTokenHandler();
- var parameters = new TokenValidationParameters
- {
- ValidateIssuer = true,
- ValidIssuer = jwtOptions.Issuer,
- ValidateAudience = true,
- ValidAudience = jwtOptions.Audience,
- ValidateIssuerSigningKey = true,
- IssuerSigningKey = new RsaSecurityKey(rsa),
- ValidateLifetime = true,
- ClockSkew = TimeSpan.FromMinutes(1)
- };
-
- return handler.ValidateToken(token, parameters, out _);
- }
-
- /// Mirrors Program.cs's OnTokenValidated mapping — see class remarks.
- private static async Task TryAttachLocalRoleClaimsAsync(ClaimsPrincipal principal, IUserRepository userRepo)
- {
- var subClaim = principal.FindFirst("sub")?.Value ?? principal.FindFirst(ClaimTypes.NameIdentifier)?.Value;
- if (!Guid.TryParse(subClaim, out var userId))
- return false;
-
- var user = await userRepo.GetByIdAsync(userId);
- if (user is null || !user.IsActive)
- return false;
-
- var identity = (ClaimsIdentity)principal.Identity!;
- identity.AddClaim(new Claim("username", user.Username));
- identity.AddClaim(new Claim("role_id", user.FK_RoleId.ToString()));
- identity.AddClaim(new Claim("role_level", (user.Role?.Level ?? 0).ToString()));
- return true;
- }
-
- private static bool TryGetToken(HttpContext context, out string token)
- {
- token = string.Empty;
-
- if (TryGetBearerToken(context.Request.Headers.Authorization, out token))
- {
- return true;
- }
-
- var headerToken = context.Request.Headers["MobileAuthToken"].FirstOrDefault();
- if (TryGetBearerToken(headerToken, out token))
- {
- return true;
- }
-
- var cookieToken = context.Request.Cookies["access_token"];
- if (!string.IsNullOrWhiteSpace(cookieToken))
- {
- token = cookieToken.Trim();
- return true;
- }
-
- return false;
- }
-
- private static bool TryGetBearerToken(string? authorizationHeader, out string token)
- {
- token = string.Empty;
-
- if (string.IsNullOrWhiteSpace(authorizationHeader))
- {
- return false;
- }
-
- const string bearerPrefix = "Bearer ";
- if (!authorizationHeader.StartsWith(bearerPrefix, StringComparison.OrdinalIgnoreCase))
- {
- token = authorizationHeader.Trim();
- return !string.IsNullOrWhiteSpace(token);
- }
-
- token = authorizationHeader[bearerPrefix.Length..].Trim();
- return !string.IsNullOrWhiteSpace(token);
- }
-
- ///
- /// Adapted from OSMCore's path list: this project has no Shopify-style webhook route, so that
- /// skip is dropped; /api/auth is narrowed to just login/register (this project's /api/auth/me
- /// and /api/auth/logout are meant to require auth, unlike a blanket "/api/auth" skip).
- ///
- private static bool ShouldSkipAuthentication(PathString path)
- => path.Equals("/health", StringComparison.OrdinalIgnoreCase)
- || path.Equals("/api/auth/login", StringComparison.OrdinalIgnoreCase)
- || path.Equals("/api/auth/register", StringComparison.OrdinalIgnoreCase)
- || path.StartsWithSegments("/swagger", StringComparison.OrdinalIgnoreCase);
-
- private static void PopulateContextItems(HttpContext context, ClaimsPrincipal principal)
- {
- context.Items["UserId"] = principal.FindFirst("sub")?.Value ?? principal.FindFirst(ClaimTypes.NameIdentifier)?.Value;
- context.Items["Username"] = principal.FindFirst("username")?.Value;
- context.Items["RoleId"] = principal.FindFirst("role_id")?.Value;
- context.Items["RoleLevel"] = principal.FindFirst("role_level")?.Value;
- }
-
- private static async Task RejectAsync(HttpContext context, string message)
- {
- context.Response.StatusCode = StatusCodes.Status401Unauthorized;
- await context.Response.WriteAsJsonAsync(new ApiResponse
-