From d12a8fed5141afca15dc21505413ba94d99b9971 Mon Sep 17 00:00:00 2001 From: tahah02 Date: Fri, 21 Nov 2025 16:54:49 +0500 Subject: [PATCH 1/2] Added comprehensive Project Documentation (README) --- .../Controllers/AccountController.cs | 4 +- EasyPay.WebAPI/Controllers/AuthController.cs | 37 +++++++++++++++ EasyPay.WebAPI/EasyPay.WebAPI.csproj | 5 ++ .../Middlewares/LoggingMiddleware.cs | 12 +++-- EasyPay.WebAPI/Program.cs | 47 +++++++++++++++++-- EasyPay.WebAPI/appsettings.json | 10 +++- 6 files changed, 104 insertions(+), 11 deletions(-) create mode 100644 EasyPay.WebAPI/Controllers/AuthController.cs diff --git a/EasyPay.WebAPI/Controllers/AccountController.cs b/EasyPay.WebAPI/Controllers/AccountController.cs index 972c6af..248f33a 100644 --- a/EasyPay.WebAPI/Controllers/AccountController.cs +++ b/EasyPay.WebAPI/Controllers/AccountController.cs @@ -1,5 +1,6 @@ using EasyPay.Data.Dtos; using EasyPay.Logic; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; @@ -23,7 +24,8 @@ public IActionResult GetBalance(string userId) var response = _manager.GetBalance(userId); return Ok(response); } - + // Transfer + [Authorize] [HttpPost("transfer")] public IActionResult Transfer([FromBody] TransferRequestDto request) { diff --git a/EasyPay.WebAPI/Controllers/AuthController.cs b/EasyPay.WebAPI/Controllers/AuthController.cs new file mode 100644 index 0000000..4044df1 --- /dev/null +++ b/EasyPay.WebAPI/Controllers/AuthController.cs @@ -0,0 +1,37 @@ +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using EasyPay.Logic; +using EasyPay.Data.Dtos; + +namespace EasyPay.WebAPI.Controllers +{ + [Route("api/[controller]")] + [ApiController] + public class AuthController : ControllerBase + { + private readonly ITransactionManager _manager; + + // Dependency Injection (Logic Layer mangwaya) + public AuthController(ITransactionManager manager) + { + _manager = manager; + } + + // POST: api/Auth/login + [HttpPost("login")] + public IActionResult Login([FromBody] LoginDto request) + { + // 1. Logic layer ko bulao + var response = _manager.Login(request); + + // 2. Agar fail hua (Ghalat password/User nahi mila) + if (!response.IsSuccess) + { + return Unauthorized(response); // 401 Error wapas karo + } + + // 3. Agar pass hua to Token wapas karo + return Ok(response); + } + } +} diff --git a/EasyPay.WebAPI/EasyPay.WebAPI.csproj b/EasyPay.WebAPI/EasyPay.WebAPI.csproj index e825ee0..9dea67b 100644 --- a/EasyPay.WebAPI/EasyPay.WebAPI.csproj +++ b/EasyPay.WebAPI/EasyPay.WebAPI.csproj @@ -8,6 +8,7 @@ + all @@ -25,4 +26,8 @@ + + + + diff --git a/EasyPay.WebAPI/Middlewares/LoggingMiddleware.cs b/EasyPay.WebAPI/Middlewares/LoggingMiddleware.cs index cdb4617..8ae014d 100644 --- a/EasyPay.WebAPI/Middlewares/LoggingMiddleware.cs +++ b/EasyPay.WebAPI/Middlewares/LoggingMiddleware.cs @@ -4,7 +4,9 @@ using System.IO; using System.Text; using System.Text.Json; -using System.Threading.Tasks; +using System.Threading.Tasks; +using EasyPay.Data.GeneratedModels.Logs; + namespace EasyPay.WebAPI.Middlewares { @@ -17,7 +19,7 @@ public LoggingMiddleware(RequestDelegate next) _next = next; } - public async Task Invoke(HttpContext context, EasyPayDbContext dbContext) + public async Task Invoke(HttpContext context, EasyPayLogsDbContext logsdbContext) { // 1. Request Read context.Request.EnableBuffering(); @@ -61,7 +63,7 @@ public async Task Invoke(HttpContext context, EasyPayDbContext dbContext) context.Response.Body.Position = 0; // 4. Save to DB - var log = new ApiLog + var log = new EasyPay.Data.GeneratedModels.Logs.ApiLog { RequestTime = DateTime.Now, UserId = userId, @@ -74,8 +76,8 @@ public async Task Invoke(HttpContext context, EasyPayDbContext dbContext) Method = method, }; - dbContext.ApiLogs.Add(log); - await dbContext.SaveChangesAsync(); + logsdbContext.ApiLogs.Add(log); + await logsdbContext.SaveChangesAsync(); await responseBody.CopyToAsync(originalBodyStream); } diff --git a/EasyPay.WebAPI/Program.cs b/EasyPay.WebAPI/Program.cs index 4f6a1f2..1b2c3dd 100644 --- a/EasyPay.WebAPI/Program.cs +++ b/EasyPay.WebAPI/Program.cs @@ -1,21 +1,50 @@ using EasyPay.Data.GeneratedModels; // <-- Ye EasyPayDbContext ke liye hai +using EasyPay.Data.GeneratedModels.Logs; using EasyPay.Logic; // <-- Ye TransactionManager ke liye hai using EasyPay.WebAPI.Middlewares; using FluentValidation; using FluentValidation.AspNetCore; +using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.EntityFrameworkCore; +using Microsoft.IdentityModel.Tokens; +using System.Text; using System.Transactions; var builder = WebApplication.CreateBuilder(args); // 1. Controllers aur Validation add karna builder.Services.AddControllers(); +var jwtSettings = builder.Configuration.GetSection("JwtSettings"); +var key = Encoding.ASCII.GetBytes(jwtSettings["Key"]); + +builder.Services.AddAuthentication(options => +{ + options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; + options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; +}) +.AddJwtBearer(options => +{ + options.RequireHttpsMetadata = false; + options.SaveToken = true; + options.TokenValidationParameters = new TokenValidationParameters + { + ValidateIssuerSigningKey = true, + IssuerSigningKey = new SymmetricSecurityKey(key), + ValidateIssuer = true, + ValidateAudience = true, + ValidIssuer = jwtSettings["Issuer"], + ValidAudience = jwtSettings["Audience"], + ClockSkew = TimeSpan.Zero + }; +}); builder.Services.AddFluentValidationAutoValidation(); builder.Services.AddValidatorsFromAssemblyContaining(); // 2. Database Connection (Ab hum Scaffolded Context use kar rahe hain) builder.Services.AddDbContext(options => options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"))); +builder.Services.AddDbContext(options => + options.UseSqlServer(builder.Configuration.GetConnectionString("LogsConnection"))); // 3. Logic Layer (Dependency Injection) builder.Services.AddScoped(); @@ -24,6 +53,9 @@ builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); + + + var app = builder.Build(); // Configure the HTTP request pipeline. @@ -35,11 +67,20 @@ app.UseHttpsRedirection(); -// 5. Jasoos Camera ON karna (Logging Middleware) -app.UseMiddleware(); +// 1. Pehle CORS (Agar hai) +app.UseCors("AllowAll"); + +// 2. Phir Routing +app.UseRouting(); + +// 3. Authentication (ID Card Check) <-- YE NAYA HAI +app.UseAuthentication(); +// 4. Authorization (Gate Pass Check) <-- YE NAYA HAI app.UseAuthorization(); -app.MapControllers(); +// 5. Logging (Jasoosi) +app.UseMiddleware(); +app.MapControllers(); app.Run(); \ No newline at end of file diff --git a/EasyPay.WebAPI/appsettings.json b/EasyPay.WebAPI/appsettings.json index 3851f9f..a42d66b 100644 --- a/EasyPay.WebAPI/appsettings.json +++ b/EasyPay.WebAPI/appsettings.json @@ -7,7 +7,13 @@ }, "AllowedHosts": "*", "ConnectionStrings": { - // Niche dekhein: Aapke Server ka poora naam dala hai (Double slash ke saath) - "DefaultConnection": "Server=DESKTOP-BNT57LQ\\MSSQLSERVER01;Database=EasyPayDb;Trusted_Connection=True;TrustServerCertificate=True;" + "DefaultConnection": "Data Source=DESKTOP-BNT57LQ\\MSSQLSERVER01;Initial Catalog=EasyPayDb;Integrated Security=True;TrustServerCertificate=True;MultipleActiveResultSets=true;Connection Timeout=30;Connection Lifetime=0;Min Pool Size=0;Max Pool Size=1000;Pooling=true", + "LogsConnection": "Data Source=DESKTOP-BNT57LQ\\MSSQLSERVER01;Initial Catalog=EasyPayLogsDB;Integrated Security=True;TrustServerCertificate=True;MultipleActiveResultSets=true;Connection Timeout=30;Connection Lifetime=0;Min Pool Size=0;Max Pool Size=1000;Pooling=true" + }, + "JwtSettings": { + "Key": "YeMeraSuperSecretKeyHaiJo32CharsKaHonaChahiye123", + "Issuer": "EasyPayServer", + "Audience": "EasyPayClient" } + } \ No newline at end of file From 6147ac533179ed1e78efe599f38b2a582ed7909a Mon Sep 17 00:00:00 2001 From: tahah02 Date: Fri, 21 Nov 2025 16:55:52 +0500 Subject: [PATCH 2/2] Added Readme Documentation --- EasyPay.Data/Dtos/LoginDto.cs | 14 +++++++ EasyPay.Logic/ITransactionManager.cs | 1 + EasyPay.Logic/TransactionManager.cs | 56 +++++++++++++++++++++++++--- 3 files changed, 65 insertions(+), 6 deletions(-) create mode 100644 EasyPay.Data/Dtos/LoginDto.cs diff --git a/EasyPay.Data/Dtos/LoginDto.cs b/EasyPay.Data/Dtos/LoginDto.cs new file mode 100644 index 0000000..1a69a90 --- /dev/null +++ b/EasyPay.Data/Dtos/LoginDto.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EasyPay.Data.Dtos +{ + public class LoginDto + { + public string UserId { get; set; } + public string Password { get; set; } + } +} diff --git a/EasyPay.Logic/ITransactionManager.cs b/EasyPay.Logic/ITransactionManager.cs index 8250351..0e1f2c7 100644 --- a/EasyPay.Logic/ITransactionManager.cs +++ b/EasyPay.Logic/ITransactionManager.cs @@ -15,5 +15,6 @@ public interface ITransactionManager ApiResponse GetBalance(string userId); ApiResponse TransferMoney(TransferRequestDto request); ApiResponse SetPassword(SetPasswordDto request); + ApiResponse Login(LoginDto request); } } diff --git a/EasyPay.Logic/TransactionManager.cs b/EasyPay.Logic/TransactionManager.cs index 73ba94a..5f03911 100644 --- a/EasyPay.Logic/TransactionManager.cs +++ b/EasyPay.Logic/TransactionManager.cs @@ -4,16 +4,60 @@ using System; using System.Collections.Generic; using System.Linq; +using Microsoft.Extensions.Configuration; +using Microsoft.IdentityModel.Tokens; +using System.IdentityModel.Tokens.Jwt; +using System.Security.Claims; +using System.Text; namespace EasyPay.Logic { public class TransactionManager : ITransactionManager { private readonly EasyPayDbContext _context; - - public TransactionManager(EasyPayDbContext context) + private readonly IConfiguration _config; + public TransactionManager(EasyPayDbContext context, IConfiguration config) { _context = context; + _config = config; + } + + // Login Method + public ApiResponse Login(LoginDto request) + { + string logId = "LOGIN-" + Guid.NewGuid().ToString().Substring(0, 8).ToUpper(); + + // A. User Check + var user = _context.UserAccounts.FirstOrDefault(u => u.UserId == request.UserId); + if (user == null) return new ApiResponse { LogId = logId, IsSuccess = false, Message = "User Not Found" }; + + // B. Password Check (Hash match) + string inputHash = SecurityHelper.HashPassword(request.Password); + if (user.PasswordHash != inputHash) return new ApiResponse { LogId = logId, IsSuccess = false, Message = "Wrong Password" }; + + // C. Token Generation (Secret Key use karke) + var key = Encoding.ASCII.GetBytes(_config["JwtSettings:Key"]); + var tokenHandler = new JwtSecurityTokenHandler(); + + var tokenDescriptor = new SecurityTokenDescriptor + { + Subject = new ClaimsIdentity(new[] { new Claim(ClaimTypes.NameIdentifier, user.UserId) }), + Expires = DateTime.UtcNow.AddMinutes(30), + Issuer = _config["JwtSettings:Issuer"], + Audience = _config["JwtSettings:Audience"], + SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature) + }; + + var token = tokenHandler.CreateToken(tokenDescriptor); + string finalToken = tokenHandler.WriteToken(token); + + return new ApiResponse + { + LogId = logId, + IsSuccess = true, + Message = "Login Successful", + Data = finalToken + }; } // Helper to generate ID @@ -151,7 +195,7 @@ public ApiResponse SetPassword(SetPasswordDto request) { string logId = "PWD-" + Guid.NewGuid().ToString().Substring(0, 8).ToUpper(); - // 1. User dhoondo + // 1. Find User var user = _context.UserAccounts.FirstOrDefault(u => u.UserId == request.UserId); if (user == null) @@ -160,15 +204,15 @@ public ApiResponse SetPassword(SetPasswordDto request) { LogId = logId, IsSuccess = false, - Message = "User nahi mila!", + Message = "User not Found", Data = null }; } - // 2. Password ko Hash karo (Kachumar nikalo) + // 2. Password Hashing string hashedPassword = SecurityHelper.HashPassword(request.NewPassword); - // 3. Database mein Hash save karo + // 3. Save Hash In DB user.PasswordHash = hashedPassword; _context.SaveChanges();