Add project files.

This commit is contained in:
2024-03-06 22:56:56 +05:30
parent 7fa8f770f7
commit 36feb20d97
12 changed files with 595 additions and 0 deletions
+30
View File
@@ -0,0 +1,30 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.8" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.8">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.8" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.8">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.IdentityModel.Tokens" Version="6.21.0" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="6.0.14" />
<PackageReference Include="Serilog.AspNetCore" Version="8.0.1" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
<PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="7.0.2" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.21.0" />
</ItemGroup>
</Project>
+25
View File
@@ -0,0 +1,25 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.6.33723.286
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "APISocietyToolBox", "APISocietyToolBox.csproj", "{A6B7E065-A6A6-4C1F-B798-585296385926}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A6B7E065-A6A6-4C1F-B798-585296385926}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A6B7E065-A6A6-4C1F-B798-585296385926}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A6B7E065-A6A6-4C1F-B798-585296385926}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A6B7E065-A6A6-4C1F-B798-585296385926}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {A9EDFC27-34DB-4EBD-AB43-F9D4FE484068}
EndGlobalSection
EndGlobal
+217
View File
@@ -0,0 +1,217 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Security.Cryptography;
using APISocietyToolBox.Models;
using APISocietyToolBox.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.Data.SqlClient;
namespace APISocietyToolBox.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class JWTAuthController : Controller
{
public static UserModel user = new UserModel();
private readonly IConfiguration _configuration;
//private readonly IUserService _userService;
private readonly DataContext _Context;
public JWTAuthController(IConfiguration configuration, DataContext context) //, IUserService userService
{
_configuration = configuration;
//_userService = userService;
_Context = context;
}
[HttpGet, Authorize]
public ActionResult<string> GetMe()
{
var userName = ""; // _userService.GetMyName();
return Ok(userName);
}
[HttpPost("login")]
public async Task<ActionResult<string>> Login(UserDto request)
{
var pUsername = new SqlParameter("@Username", request.Username);
var pQueryResponse = await _Context.LoginUserValidate.FromSqlRaw($"sp_ValidateUser @UserName", pUsername).ToListAsync();
if (pQueryResponse[0].UserName != request.Username)
{
return BadRequest("User not found.");
}
if (!VerifyPasswordHash(request.Password, pQueryResponse[0].LoginPassword, pQueryResponse[0].PasswordSalt))
{
return BadRequest("Wrong password.");
}
var Token = CreateToken(pQueryResponse[0]);
var refreshToken = GenerateRefreshToken();
user.UserID = pQueryResponse[0].UserID;
user.UserName = pQueryResponse[0].UserName;
user.UserRole = pQueryResponse[0].UserRole;
user.UserRoleID = pQueryResponse[0].UserRoleID;
user.PropertyID = pQueryResponse[0].PropertyID;
user.RefreshToken = Token;
user.TokenExpires = refreshToken.Expires;
user.TokenCreated = refreshToken.Created;
SetRefreshToken(user);
return Ok(user);
}
[HttpPost("refresh-token")]
public async Task<ActionResult<string>> RefreshToken(UserTokenRefreshModel user)
{
var pRefreshToken = new SqlParameter("@RefreshToken", user.RefreshToken);
var pQuery = _Context.getUserToken.FromSqlRaw($"sp_getUserToken @RefreshToken", pRefreshToken).ToList();
//Console.WriteLine(pQuery);
var pQueryResponse = await _Context.getUserToken.FromSqlRaw($"sp_getUserToken @RefreshToken", pRefreshToken).ToListAsync();
if (pQueryResponse[0].Status != 200)
{
return Unauthorized(pQueryResponse[0]);
}
else
{
string refreshToken = pQueryResponse[0].RefreshToken.ToString();
if (!user.RefreshToken.Equals(refreshToken))
{
return Unauthorized("Invalid Refresh Token.");
}
//else if (user.TokenExpires < DateTime.Now)
//{
// return Unauthorized("Token expired.");
//}
LoginResponseModel usrResponse = new LoginResponseModel();
UserModel usr = new UserModel();
usrResponse.UserName = user.UserName;
usrResponse.UserRole = user.UserRole;
string token = CreateToken(usrResponse);
var newRefreshToken = GenerateRefreshToken();
usr.UserID = pQueryResponse[0].UserID;
usr.UserRoleID = pQueryResponse[0].UserRoleID;
usr.UserName = user.UserName;
usr.UserRole = user.UserRole;
usr.PropertyID = pQueryResponse[0].PropertyID;
usr.RefreshToken = token.ToString();
usr.TokenCreated = newRefreshToken.Created;
usr.TokenExpires = newRefreshToken.Expires;
SetRefreshToken(usr);
pQueryResponse[0].RefreshToken = usr.RefreshToken;
pQueryResponse[0].UserRole = user.UserRole;
pQueryResponse[0].UserName = user.UserName;
pQueryResponse[0].TokenCreated = newRefreshToken.Created;
pQueryResponse[0].TokenExpires = newRefreshToken.Expires;
//pQueryResponse[0].UserLocation=usr.UserLocation;
return Ok(pQueryResponse[0]);
}
}
private RefreshToken GenerateRefreshToken()
{
var refreshToken = new RefreshToken
{
Token = Convert.ToBase64String(RandomNumberGenerator.GetBytes(64)),
Expires = DateTime.Now.AddDays(1),
Created = DateTime.Now
};
return refreshToken;
}
private void SetRefreshToken(UserModel usr)
{
try
{
//Response.Cookies.Append("refreshToken", newRefreshToken.Token, cookieOptions);
UserTokens oUserTokens = new UserTokens();
oUserTokens.UserID = usr.UserID;
oUserTokens.UserRoleID = usr.UserRoleID;
oUserTokens.PropertyID = usr.PropertyID;
oUserTokens.RefreshToken = usr.RefreshToken;
oUserTokens.TokenCreated = usr.TokenCreated;
oUserTokens.TokenExpires = usr.TokenExpires;
_Context.UserTokens.Add(oUserTokens);
_Context.SaveChanges();
}
catch (Exception ex)
{
Console.WriteLine(ex.InnerException);
}
}
private string CreateToken(LoginResponseModel user)
{
List<Claim> claims = new List<Claim>
{
new Claim(ClaimTypes.Name, user.UserName),
new Claim(ClaimTypes.Role, user.UserRole)
};
var key = new SymmetricSecurityKey(System.Text.Encoding.UTF8.GetBytes(_configuration.GetSection("AppSettings:Token").Value));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha512);
var token = new JwtSecurityToken(
claims: claims,
expires: DateTime.Now.AddDays(1),
signingCredentials: creds);
var jwt = new JwtSecurityTokenHandler().WriteToken(token);
return jwt;
}
private bool VerifyPasswordHash(string password, string passwordHash, string passwordSalt)
{
byte[] pbytepasswordSalt = StringToByteArray(passwordSalt);
byte[] pbytepasswordHash = StringToByteArray(passwordHash);
using (var hmac = new HMACSHA512(pbytepasswordSalt))
{
var computedHash = hmac.ComputeHash(System.Text.Encoding.UTF8.GetBytes(password));
return computedHash.SequenceEqual(pbytepasswordHash);
}
}
public static byte[] StringToByteArray(string hex)
{
int length = hex.Length / 2;
byte[] byteArray = new byte[length];
for (int i = 0; i < length; i++)
{
byteArray[i] = Convert.ToByte(hex.Substring(i * 2, 2), 16);
}
return byteArray;
}
}
}
+33
View File
@@ -0,0 +1,33 @@
using Microsoft.AspNetCore.Mvc;
namespace APISocietyToolBox.Controllers
{
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
_logger = logger;
}
[HttpGet(Name = "GetWeatherForecast")]
public IEnumerable<WeatherForecast> Get()
{
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray();
}
}
}
+23
View File
@@ -0,0 +1,23 @@
using APISocietyToolBox.Models;
using Microsoft.EntityFrameworkCore;
namespace APISocietyToolBox.Data
{
public class DataContext : DbContext
{
public DataContext(DbContextOptions<DataContext> options) : base(options) { }
public DbSet<UserResponseModel> UserCreate { get; set; }
public DbSet<LoginResponseModel> LoginUserValidate { get; set; }
public DbSet<UserTokenModel> getUserToken { get; set; }
public DbSet<UserTokens> UserTokens { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<UserTokenModel>().HasNoKey();
}
}
}
+8
View File
@@ -0,0 +1,8 @@
namespace APISocietyToolBox.Models
{
public class UserDto
{
public string Username { get; set; } = string.Empty;
public string Password { get; set; } = string.Empty;
}
}
+110
View File
@@ -0,0 +1,110 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace APISocietyToolBox.Models
{
public class UserModel
{
public Int64? UserID { get; set; } = null;
public string UserName { get; set; } = string.Empty;
public string LoginName { get; set; } = string.Empty;
public string LoginPassword { get; set; } = string.Empty;
public string PasswordSalt { get; set; } = string.Empty;
public string UserRole { get; set; } = string.Empty;
public Int64? UserRoleID { get; set; }
public Int64? PropertyID { get; set; }
public string? RefreshToken { get; set; } = string.Empty;
public DateTime? TokenCreated { get; set; }
public DateTime? TokenExpires { get; set; }
}
public class UserTokenRefreshModel
{
public Int64 UserID { get; set; }
public int UserRoleID { get; set; }
public string? UserName { get; set; } = string.Empty;
public string? UserRole { get; set; } = string.Empty;
public string? RefreshToken { get; set; } = string.Empty;
}
public class UserTokenModel
{
public int? Status { get; set; }
public string StatusMessage { get; set; } = string.Empty;
public string? UserName { get; set; } = string.Empty;
public string? UserRole { get; set; } = string.Empty;
public Int64? UserRoleID { get; set; } = null;
public Int64? UserID { get; set; } = null;
public int PropertyID { get; set; }
public string? RefreshToken { get; set; } = string.Empty;
public DateTime? TokenCreated { get; set; }
public DateTime? TokenExpires { get; set; }
}
public class LoginResponseModel
{
public int? Status { get; set; }
public string StatusMessage { get; set; } = string.Empty;
[Key]
public Int64 UserID { get; set; }
public Int64 UserRoleID { get; set; }
public string UserRole { get; set; } = string.Empty;
public string UserName { get; set; } = string.Empty;
public string LoginPassword { get; set; } = string.Empty;
public string PasswordSalt { get; set; } = string.Empty;
public Int64 PropertyID { get; set; }
}
public class UserResponseModel
{
[Key]
public Int64 UserID { get; set; }
public string UserName { get; set; } = string.Empty;
public int Status { get; set; }
public string StatusMessage { get; set; } = string.Empty;
}
public class UserRequestModel
{
public string UserName { get; set; } = string.Empty;
public string LoginName { get; set; } = string.Empty;
public string LoginPassword { get; set; } = string.Empty;
public string UserRole { get; set; } = string.Empty;
public int UserRoleID { get; set; }
public int PropertyID { get; set; }
public string? RefreshToken { get; set; } = string.Empty;
public DateTime? TokenCreated { get; set; }
public DateTime? TokenExpires { get; set; }
}
public class UserTokens
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Int64 UserTokenID { get; set; }
public Int64? UserID { get; set; }
public Int64? UserRoleID { get; set; }
public Int64? PropertyID { get; set; }
public string? RefreshToken { get; set; }
public DateTime? TokenExpires { get; set; }
public DateTime? TokenCreated { get; set; }
}
public class RefreshToken
{
public string Token { get; set; } = string.Empty;
public DateTime Created { get; set; } = DateTime.Now;
public DateTime Expires { get; set; }
public int UserID { get; set; }
public string UserName { get; set; } = string.Empty;
public int PropertyID { get; set; }
}
}
+82
View File
@@ -0,0 +1,82 @@
using Serilog.Events;
using Serilog;
using Microsoft.Data.SqlClient;
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.Filters;
using System.Text;
using APISocietyToolBox.Data;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Information()
.MinimumLevel.Override("Microsoft", LogEventLevel.Warning) // Adjust log levels if needed
.Enrich.FromLogContext()
.WriteTo.Console()
.WriteTo.File("c:/users/public/ApiRetailLogs/apiSocietyToolBoxlogfile.txt")
.CreateLogger();
builder.Host.UseSerilog();
builder.Services.AddControllers();
builder.Services.AddDbContext<DataContext>(options =>
{
options.UseSqlServer(builder.Configuration.GetConnectionString("SQLServerConnection"));
options.LogTo(Console.WriteLine, LogLevel.Information);
SqlConnection.ClearAllPools();
});
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddHttpContextAccessor();
builder.Services.AddSwaggerGen(options =>
{
options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
{
Description = "Standard Authorization header using the Bearer scheme (\"bearer {token}\")",
In = ParameterLocation.Header,
Name = "Authorization",
Type = SecuritySchemeType.ApiKey
});
options.OperationFilter<SecurityRequirementsOperationFilter>();
});
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8
.GetBytes(builder.Configuration.GetSection("AppSettings:Token").Value)),
ValidateIssuer = false,
ValidateAudience = false
};
});
builder.Services.AddCors(options => options.AddPolicy(name: "NgOrigins",
policy =>
{
policy.WithOrigins("http://localhost:4200").AllowAnyMethod().AllowAnyHeader();
}));
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseAuthorization();
app.MapControllers();
app.Run();
+31
View File
@@ -0,0 +1,31 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:24037",
"sslPort": 0
}
},
"profiles": {
"APISocietyToolBox": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "http://localhost:5232",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
+13
View File
@@ -0,0 +1,13 @@
namespace APISocietyToolBox
{
public class WeatherForecast
{
public DateTime Date { get; set; }
public int TemperatureC { get; set; }
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
public string? Summary { get; set; }
}
}
+8
View File
@@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}
+15
View File
@@ -0,0 +1,15 @@
{
"ConnectionStrings": {
"SQLServerConnection": "server=ROGFLOWX13\\SQL2014;Database=SocietyToolbox;User Id=sa;Password=ift@!234;TrustServerCertificate=True"
},
"AppSettings": {
"Token": "MXZUOPUW1K9R5JJFACTVDIZKLABYPADTNZBSMA9869EZFKWJ3R9VG2KY2NRCKUS2"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}