Compare commits

..

17 Commits
repos ... main

Author SHA1 Message Date
Nikolai Papin
feee23f1a8 Services connected in Program.cs 2024-09-07 17:24:12 +03:00
ereshkigal
97d53618f6 services 2024-09-07 17:09:18 +03:00
ereshkigal
c1b3843e2a user service operaional 2024-09-07 15:24:05 +03:00
ereshkigal
c39b481eb8 Merge branch 'main' of ssh://git.georesinwaybill.ru:222/espada/renis-backend 2024-09-07 15:14:58 +03:00
ereshkigal
db5c523af5 Random user generation begin 2024-09-07 15:13:38 +03:00
Nikolai Papin
a2e38d2ba9 Actually added auth 2024-09-07 13:59:48 +03:00
Nikolai Papin
1afb436c9c Authorization and authentication in program.cs + deps 2024-09-07 13:59:00 +03:00
401dc69f5e Merge pull request 'jwt service' (#2) from auth into main
Reviewed-on: https://git.georesinwaybill.ru/espada/renis-backend/pulls/2
2024-09-07 10:39:59 +00:00
Nikolai Papin
5595730885 jwt service 2024-09-07 13:34:38 +03:00
ereshkigal
a670b00308 Merge branch 'main' of https://git.georesinwaybill.ru/espada/renis-backend 2024-09-07 12:45:54 +03:00
ereshkigal
5eb296ffe3 UserService preparation 2024-09-07 12:45:00 +03:00
Nikolai Papin
e45c143afc UserPolis repo 2024-09-07 12:42:31 +03:00
Nikolai Papin
d75f179ad4 Car, Polis & User repos + moved to dedicated folders 2024-09-07 12:34:55 +03:00
Nikolai Papin
83c9b7fe6e verified field in car, fixed missing public declarations there as well 2024-09-07 12:18:30 +03:00
e1f9b65d84 Merge pull request 'repos' (#1) from repos into main
Reviewed-on: https://git.georesinwaybill.ru/espada/renis-backend/pulls/1
2024-09-07 09:15:10 +00:00
ereshkigal
f9653dd01f logging operational 2024-09-07 12:13:28 +03:00
ereshkigal
5ea14bcab3 preparing logs 2024-09-07 11:59:23 +03:00
68 changed files with 1790 additions and 7 deletions

1
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1 @@
{}

19
DTO/UserDto.cs Normal file
View File

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.ComponentModel.DataAnnotations;
namespace renis_backend.DTO
{
public class UserDto
{
[Required]
public string Name { get; set; } = null!;
[Phone]
[Required]
public string Phone { get; set; } = null!;
[Required]
public string Password { get; set; } = null!;
}
}

View File

@ -9,11 +9,12 @@ public class Car
[Required] [Required]
public string Number { get; set; } = null!; public string Number { get; set; } = null!;
[Required] [Required]
Polis Polis { get; set; } = null!; public Polis Polis { get; set; } = null!;
[Required] [Required]
long PolisId { get; set; } public long PolisId { get; set; }
[Required] [Required]
User Resp { get; set; } = null!; public User Resp { get; set; } = null!;
[Required] [Required]
long RespId { get; set; } public long RespId { get; set; }
public bool Verified { get; set; }
} }

View File

@ -13,4 +13,6 @@ public class User
public string Phone { get; set; } = null!; public string Phone { get; set; } = null!;
[Required] [Required]
public string Password { get; set; } = null!; public string Password { get; set; } = null!;
[Required]
public DateTime PasswordChangeDate { get; set; } = DateTime.UtcNow;
} }

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace renis_backend.Exceptions.User
{
public class UserException : System.Exception
{
public UserException() { }
public UserException(string message) : base(message) { }
public UserException(string message, System.Exception inner) : base(message, inner) { }
}
}

View File

@ -1,10 +1,46 @@
using Serilog;
using Serilog.Exceptions;
using System.Text;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using Renis.Database;
using Microsoft.EntityFrameworkCore;
using Renis.Repositories;
using Renis.Services.Jwt;
using renis_backend.Services.Polis;
using renis_backend.Services;
using renis_backend.Services.UserPolises;
using renis_backend.Services.Users;
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
// Add services to the container. // Database context
builder.Services.AddDbContext<ApplicationContext>(x => {
var Hostname=Environment.GetEnvironmentVariable("DB_HOSTNAME") ?? "localhost";
var Port=Environment.GetEnvironmentVariable("DB_PORT") ?? "5432";
var Name=Environment.GetEnvironmentVariable("DB_NAME") ?? "postgres";
var Username=Environment.GetEnvironmentVariable("DB_USERNAME") ?? "postgres";
var Password=Environment.GetEnvironmentVariable("DB_PASSWORD") ?? "postgres";
x.UseNpgsql($"Server={Hostname}:{Port};Database={Name};Uid={Username};Pwd={Password};");
});
// Repos
builder.Services.AddScoped<IUserRepository, UserRepository>();
builder.Services.AddScoped<IPolisRepository, PolisRepository>();
builder.Services.AddScoped<IUserPolisRepository, UserPolisRepository>();
builder.Services.AddScoped<ICarRepository, CarRepository>();
// Services
builder.Services.AddScoped<IJwtService, JwtService>();
builder.Services.AddScoped<IPolisService, PolisService>();
builder.Services.AddScoped<IUserPolisService, UserPolisService>();
builder.Services.AddScoped<IUserService, UserService>();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer(); builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(); builder.Services.AddSwaggerGen();
configureLogging();
var app = builder.Build(); var app = builder.Build();
// Configure the HTTP request pipeline. // Configure the HTTP request pipeline.
@ -14,7 +50,44 @@ if (app.Environment.IsDevelopment())
app.UseSwaggerUI(); app.UseSwaggerUI();
} }
// Authorization
builder.Services.AddAuthorization();
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
string issuer = Environment.GetEnvironmentVariable("JWT_ISSUER") ?? "renis";
string audience = Environment.GetEnvironmentVariable("JWT_AUDIENCE") ?? "renis";
string secret = Environment.GetEnvironmentVariable("JWT_SECRET") ?? "TopSecretKeyForTheProtectionOfChocolateCookiesAndOtherSweetThings";
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidIssuer = issuer,
ValidateAudience = true,
ValidAudience = audience,
ValidateLifetime = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secret)),
ValidateIssuerSigningKey = true
};
});
app.UseHttpsRedirection(); app.UseHttpsRedirection();
app.Run(); app.Run();
void configureLogging(){
var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production";
var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json",optional:false,reloadOnChange:true).Build();
Console.WriteLine(environment);
Console.WriteLine(configuration);
Log.Logger = new LoggerConfiguration()
.Enrich.FromLogContext()
.Enrich.WithExceptionDetails()
.WriteTo.Debug()
.WriteTo.Console()
.Enrich.WithProperty("Environment",environment)
.ReadFrom.Configuration(configuration)
.CreateLogger();
}

View File

@ -0,0 +1,48 @@
using Microsoft.EntityFrameworkCore;
using Renis.Database;
using Renis.Database.Models;
namespace Renis.Repositories;
public class CarRepository(ApplicationContext db) : ICarRepository
{
private readonly ApplicationContext _db = db;
public async Task<bool> AddCar(Car car)
{
_db.Cars.Add(car);
return await Save();
}
public async Task<bool> DeleteCar(Car car)
{
_db.Cars.Remove(car);
return await Save();
}
public async Task<Car?> GetCarById(long id)
{
return await _db.Cars.FirstOrDefaultAsync(x => x.Id == id);
}
public async Task<Car?> GetCarByNumber(string number)
{
return await _db.Cars.FirstOrDefaultAsync(x => x.Number == number);
}
public IQueryable<Car> GetCars()
{
return _db.Cars.AsQueryable();
}
public async Task<bool> Save()
{
return await _db.SaveChangesAsync() > 0;
}
public async Task<bool> UpdateCar(Car car)
{
_db.Cars.Update(car);
return await Save();
}
}

View File

@ -0,0 +1,14 @@
using Renis.Database.Models;
namespace Renis.Repositories;
public interface ICarRepository
{
public Task<bool> AddCar(Car car);
public Task<bool> UpdateCar(Car car);
public Task<bool> DeleteCar(Car car);
public Task<Car?> GetCarById(long id);
public Task<Car?> GetCarByNumber(string number);
public IQueryable<Car> GetCars();
public Task<bool> Save();
}

View File

@ -0,0 +1,48 @@
using Microsoft.EntityFrameworkCore;
using Renis.Database;
using Renis.Database.Models;
namespace Renis.Repositories;
public class PolisRepository(ApplicationContext db) : IPolisRepository
{
private readonly ApplicationContext _db = db;
public async Task<bool> AddPolis(Polis polis)
{
_db.Polises.Add(polis);
return await Save();
}
public async Task<bool> DeletePolis(Polis polis)
{
_db.Polises.Remove(polis);
return await Save();
}
public async Task<Polis?> GetPolisById(long id)
{
return await _db.Polises.FirstOrDefaultAsync(x => x.Id == id);
}
public async Task<Polis?> GetPolisByNumber(string number)
{
return await _db.Polises.FirstOrDefaultAsync(x => x.Number == number);
}
public IQueryable<Polis> GetPolises()
{
return _db.Polises.AsQueryable();
}
public async Task<bool> Save()
{
return await _db.SaveChangesAsync() > 0;
}
public async Task<bool> UpdatePolis(Polis polis)
{
_db.Polises.Update(polis);
return await Save();
}
}

View File

@ -0,0 +1,14 @@
using Renis.Database.Models;
namespace Renis.Repositories;
public interface IUserPolisRepository
{
public Task<bool> AddUserPolis(UserPolis userPolis);
public Task<bool> UpdateUserPolis(UserPolis userPolis);
public Task<bool> DeleteUserPolis(UserPolis userPolis);
public Task<UserPolis?> GetUserPolisById(long id);
public Task<UserPolis?> GetUserPolisByUserIdAndPolisId(long userId, long polisId);
public IQueryable<UserPolis> GetUserPolises();
public Task<bool> Save();
}

View File

@ -0,0 +1,48 @@
using Microsoft.EntityFrameworkCore;
using Renis.Database;
using Renis.Database.Models;
namespace Renis.Repositories;
public class UserPolisRepository(ApplicationContext db) : IUserPolisRepository
{
private readonly ApplicationContext _db = db;
public async Task<bool> AddUserPolis(UserPolis userPolis)
{
_db.UserPolises.Add(userPolis);
return await Save();
}
public async Task<bool> UpdateUserPolis(UserPolis userPolis)
{
_db.UserPolises.Update(userPolis);
return await Save();
}
public async Task<bool> DeleteUserPolis(UserPolis userPolis)
{
_db.UserPolises.Remove(userPolis);
return await Save();
}
public async Task<UserPolis?> GetUserPolisById(long id)
{
return await _db.UserPolises.FirstOrDefaultAsync(x => x.Id == id);
}
public async Task<UserPolis?> GetUserPolisByUserIdAndPolisId(long userId, long polisId)
{
return await _db.UserPolises.FirstOrDefaultAsync(x => x.UserId == userId && x.PolisId == polisId);
}
public IQueryable<UserPolis> GetUserPolises()
{
return _db.UserPolises.AsQueryable();
}
public async Task<bool> Save()
{
return await _db.SaveChangesAsync() > 0;
}
}

View File

@ -0,0 +1,55 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Renis.Database.Models;
using Renis.Repositories;
namespace renis_backend.Services.Cars
{
public class CarsService : ICarsService
{
private readonly ICarRepository _carsRepository;
private readonly ILogger<CarsService> _logger;
public CarsService( ICarRepository carsRepository, ILogger<CarsService> logger)
{
_carsRepository = carsRepository;
_logger = logger;
}
public async Task<Car> GenerateCar(Renis.Database.Models.Polis polis, User user)
{
try
{
if(await _carsRepository.AddCar(new Car()
{
PolisId = polis.Id,
RespId = user.Id,
Verified = false,
Polis = polis,
Resp = user,
Number = GenerateRussianCarNumber()
}))
{
return await _carsRepository.GetCarByNumber(GenerateRussianCarNumber());
}
throw new Exception("Car not created");
}
catch(Exception ex)
{
_logger.LogError(ex.Message);
throw;
}
}
private string GenerateRussianCarNumber()
{
string letters = "АВЕКМНОРСТУХ";
string numbers = "0123456789";
string regionCode = new string(Enumerable.Repeat(numbers, 2).Select(c => c[new Random().Next(c.Length)]).ToArray());
string series = new string(Enumerable.Repeat(letters, 3).Select(c => c[new Random().Next(c.Length)]).ToArray());
string number = new string(Enumerable.Repeat(numbers, 3).Select(c => c[new Random().Next(c.Length)]).ToArray());
return $"{series} {number} {regionCode}";
}
}
}

View File

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace renis_backend.Services.Cars
{
public interface ICarsService
{
public Task<Renis.Database.Models.Car> GenerateCar(Renis.Database.Models.Polis polis, Renis.Database.Models.User user);
}
}

View File

@ -0,0 +1,11 @@
using Renis.Database.Models;
namespace Renis.Services.Jwt;
public interface IJwtService
{
string GenerateAccessToken(User user);
string GenerateRefreshToken(User user);
Tuple<bool, string> ValidateAccessToken(string? token);
Task<Tuple<bool, string>> ValidateRefreshToken(string? token);
}

201
Services/Jwt/JwtService.cs Normal file
View File

@ -0,0 +1,201 @@
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using Renis.Database.Models;
using Microsoft.IdentityModel.Tokens;
using Renis.Repositories;
namespace Renis.Services.Jwt;
public class JwtService : IJwtService
{
private readonly string _secretKey;
private readonly string _issuer;
private readonly string _audience;
private readonly IUserRepository _userRepo;
private readonly ILogger<JwtService> _logger;
public JwtService(ILogger<JwtService> logger, IUserRepository userRepo)
{
_logger = logger;
_userRepo = userRepo;
// TODO: Change issuer & audience
_issuer = Environment.GetEnvironmentVariable("AUTH_JWT_ISSUER") ?? "renis";
_audience = Environment.GetEnvironmentVariable("AUTH_JWT_AUDIENCE") ?? "renis";
_secretKey = Environment.GetEnvironmentVariable("AUTH_JWT_SECRET")!;
if (_secretKey == null)
{
throw new Exception("Missing AUTH_JWT_SECRET environment variable");
}
}
/// <summary>
/// Generates an access token for the specified user.
/// </summary>
/// <param name="user">The user for whom the access token is generated.</param>
/// <returns>The generated access token as a string.</returns>
public string GenerateAccessToken(User user)
{
var tokenHandler = new JwtSecurityTokenHandler();
var key = Convert.FromBase64String(_secretKey);
var tokenDescriptor = new SecurityTokenDescriptor
{
Issuer = _issuer,
Audience = _audience,
Subject = new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.Name, user.Phone),
new Claim(ClaimsIdentity.DefaultRoleClaimType,"User"),
new Claim(ClaimTypes.AuthenticationMethod, "Access")
}),
Expires = DateTime.UtcNow.AddMinutes(50),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
};
var token = tokenHandler.CreateToken(tokenDescriptor);
return tokenHandler.WriteToken(token);
}
/// <summary>
/// Generates a refresh token for the specified user.
/// </summary>
/// <param name="user">The user for whom the refresh token is generated.</param>
/// <returns>The generated refresh token as a string.</returns>
public string GenerateRefreshToken(User user)
{
var tokenHandler = new JwtSecurityTokenHandler();
var key = Convert.FromBase64String(_secretKey);
var tokenDescriptor = new SecurityTokenDescriptor
{
Issuer = _issuer,
Audience = _audience,
Subject = new ClaimsIdentity(new[]
{
new Claim("PasswordChangeDate", user.PasswordChangeDate.ToString()),
new Claim(ClaimTypes.Name, user.Phone),
new Claim(ClaimsIdentity.DefaultRoleClaimType,"User"),
new Claim(ClaimTypes.AuthenticationMethod, "Refresh")
}),
Expires = DateTime.UtcNow.AddDays(7),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
};
var token = tokenHandler.CreateToken(tokenDescriptor);
return tokenHandler.WriteToken(token);
}
/// <summary>
/// Validates the access token and extracts the username from it if valid.
/// Returns a tuple indicating whether the token is valid and the extracted username.
/// </summary>
/// <param name="token">The access token to validate.</param>
/// <returns>A tuple indicating whether the token is valid and the extracted username.</returns>
public Tuple<bool, string> ValidateAccessToken(string? token)
{
try
{
if (token == null)
{
_logger.LogWarning("JwtService: No access token string provided");
return new (false, "");
}
var tokenHandler = new JwtSecurityTokenHandler();
var key = Convert.FromBase64String(_secretKey);
TokenValidationParameters validationParameters = new() {
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = true,
ValidIssuer = _issuer,
ValidateAudience = true,
ValidAudience = _audience,
ClockSkew = TimeSpan.Zero
};
// Валидация токена
tokenHandler.ValidateToken(token, validationParameters, out SecurityToken validatedToken);
JwtSecurityToken validatedJwt = (JwtSecurityToken)validatedToken;
var username = validatedJwt.Claims.First(claim => claim.Type == "unique_name").Value;
// Проверка типа токена
if (validatedJwt.Claims.First(claim => claim.Type == ClaimTypes.AuthenticationMethod).Value != "Access")
{
_logger.LogWarning("JwtService: the token was not a access token");
return new (false, "");
}
return new (true, username);
}
catch (Exception e)
{
_logger.LogWarning("JwtService: Token invalidated due to exception:\n{Exception}", e);
return new (false, "");;
}
}
/// <summary>
/// Validates the refresh token and extracts the username from it if valid.
/// Returns a tuple indicating whether the token is valid and the extracted username.
/// </summary>
/// <param name="token">The refresh token to validate.</param>
/// <returns>A tuple indicating whether the token is valid and the extracted username.</returns>
public async Task<Tuple<bool, string>> ValidateRefreshToken(string? token)
{
try
{
if (token == null)
{
_logger.LogWarning("JwtService: No refresh token string provided");
return new (false, "");;
}
var tokenHandler = new JwtSecurityTokenHandler();
var key = Convert.FromBase64String(_secretKey);
TokenValidationParameters validationParameters = new() {
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = true,
ValidIssuer = _issuer,
ValidateAudience = true,
ValidAudience = _audience,
ClockSkew = TimeSpan.Zero
};
// Валидация токена
tokenHandler.ValidateToken(token, validationParameters, out SecurityToken validatedToken);
JwtSecurityToken validatedJwt = (JwtSecurityToken)validatedToken;
var passwordChangeDate = validatedJwt.Claims.First(claim => claim.Type == "PasswordChangeDate").Value;
var username = validatedJwt.Claims.First(claim => claim.Type == "unique_name").Value;
// Проверка типа токена
if (validatedJwt.Claims.First(claim => claim.Type == "authmethod").Value != "Refresh")
{
_logger.LogWarning("JwtService: the token was not a refresh token");
return new (false, "");
}
var user = await _userRepo.GetUserByPhone(username);
if (user == null)
{
return new (false, "");
}
// Проверка, что дата изменения пароля совпадает с фактической
if (user.PasswordChangeDate.ToString() != passwordChangeDate)
{
username=null;
_logger.LogWarning("JwtService: the password change date was not equal to the one in the token\n1. {1}\n2. {2}", passwordChangeDate, user.PasswordChangeDate.ToString());
return new (false, "");
}
return new (true, username);
}
catch (Exception e)
{
_logger.LogWarning("JwtService: Token invalidated due to exception:\n{Exception}", e);
return new (false, "");
}
}
}

View File

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Renis.Database.Models;
namespace renis_backend.Services
{
public interface IPolisService
{
public Task<Renis.Database.Models.Polis> GeneratePolis();
public Task<Renis.Database.Models.Polis> GetPolis(long id);
}
}

View File

@ -0,0 +1,51 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Renis.Database.Models;
using Renis.Repositories;
namespace renis_backend.Services.Polis
{
public class PolisService : IPolisService
{
private readonly IPolisRepository _repository;
private readonly ILogger<PolisService> _logger;
public PolisService(IPolisRepository repository, ILogger<PolisService> logger)
{
_repository = repository;
_logger = logger;
}
public async Task<Renis.Database.Models.Polis> GeneratePolis()
{
try
{
string number = new string(Enumerable.Repeat("0123456789", 9).Select(c => c[new Random().Next(c.Length)]).ToArray());
await _repository.AddPolis( new Renis.Database.Models.Polis(){
Number = $"{number.Substring(0, 3)}-{number.Substring(3, 3)}-{number.Substring(6, 3)}",
});
return await _repository.GetPolisByNumber($"{number.Substring(0, 3)}-{number.Substring(3, 3)}-{number.Substring(6, 3)}");
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
throw;
}
}
public async Task<Renis.Database.Models.Polis> GetPolis(long id)
{
try
{
return await _repository.GetPolisById(id);
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
throw;
}
}
}
}

View File

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Renis.Database.Models;
namespace renis_backend.Services.UserPolises
{
public interface IUserPolisService
{
public Task<Renis.Database.Models.UserPolis> AddUserPolis(User user, Renis.Database.Models.Polis polis);
}
}

View File

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Renis.Database.Models;
using Renis.Repositories;
namespace renis_backend.Services.UserPolises
{
public class UserPolisService : IUserPolisService
{
private readonly IUserPolisRepository _userPolisRepository;
private readonly Logger<UserPolisService> _logger;
public UserPolisService( IUserPolisRepository userPolisRepository, Logger<UserPolisService> logger)
{
_userPolisRepository = userPolisRepository;
_logger = logger;
}
public Task<UserPolis> AddUserPolis(User user, Renis.Database.Models.Polis polis)
{
throw new NotImplementedException();
}
}
}

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Renis.Database.Models;
namespace renis_backend.Services.Users
{
public interface IUserService
{
public Task<User> GenerateUser();
public Task<User> GetUserAsync(string phone);
}
}

View File

@ -0,0 +1,110 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading.Tasks;
using Faker;
using Renis.Database.Models;
using Renis.Repositories;
using Renis.Services.Jwt;
using renis_backend.DTO;
using renis_backend.Exceptions.User;
namespace renis_backend.Services.Users
{
public class UserService : IUserService
{
private readonly ILogger<UserService> _logger;
private readonly IUserRepository _userRepository;
public UserService( ILogger<UserService> logger, IUserRepository userRepository)
{
_logger = logger;
_userRepository = userRepository;
}
public async Task<User> GetUserAsync(string phone)
{
try
{
var user = await _userRepository.GetUserByPhone(phone);
if(user == null)
{
throw new UserException("User not found");
}
return user;
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
if(ex is UserException)
{
throw;
}
throw new UserException(ex.Message);
}
}
public async Task<User> GenerateUser()
{
try
{
string firstName = russianFirstNames[random.Next(0, russianFirstNames.Length)];
string lastName = russianLastNames[random.Next(0, russianLastNames.Length)];
string patronymic = russianPatronymics[random.Next(0, russianPatronymics.Length)];
string name = $"{lastName} {firstName} {patronymic}";
string phone = GenerateRussianPhoneNumber();
string password = new string(Enumerable.Repeat("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", 10).Select(c => c[random.Next(c.Length)]).ToArray());
var user = new User
{
Name = name,
Phone = GenerateRussianPhoneNumber(),
Password = password
};
if(await _userRepository.AddUser(user))
{
return await _userRepository.GetUserByPhone(phone);
}
throw new UserException("User already exists");
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
if(ex is UserException)
{
throw;
}
throw new UserException(ex.Message);
}
}
private static Random random = new Random();
private static string[] russianFirstNames = new string[]
{
"Иван", "Петр", "Алексей", "Дмитрий", "Николай", "Сергей", "Александр", "Михаил", "Андрей", "Владимир"
};
private static string[] russianLastNames = new string[]
{
"Иванов", "Петров", "Сидоров", "Кузнецов", "Попов", "Смирнов", "Николаев", "Зайцев", "Павлов", "Михайлов"
};
private static string[] russianPatronymics = new string[]
{
"Иванович", "Петрович", "Алексеевич", "Дмитриевич", "Николаевич", "Сергеевич", "Александрович", "Михайлович", "Андреевич", "Владимирович"
};
private static string[] russianPhonePrefixes = new string[]
{
"+7", "+375", "+380", "+7"
};
private static string GenerateRussianPhoneNumber()
{
string prefix = russianPhonePrefixes[random.Next(0, russianPhonePrefixes.Length)];
string number = new string(Enumerable.Repeat("0123456789", 10).Select(c => c[random.Next(c.Length)]).ToArray());
return $"{prefix}{number}";
}
}
}

View File

@ -5,5 +5,14 @@
"Microsoft.AspNetCore": "Warning" "Microsoft.AspNetCore": "Warning"
} }
}, },
"AllowedHosts": "*" "AllowedHosts": "*",
"Serilog":{
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Information",
"System": "Warning"
}
}
}
} }

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
bin/Debug/net8.0/Npgsql.dll Executable file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
bin/Debug/net8.0/Serilog.dll Executable file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}

View File

@ -0,0 +1,18 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"Serilog":{
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Information",
"System": "Warning"
}
}
}
}

Binary file not shown.

BIN
bin/Debug/net8.0/renis-backend Executable file

Binary file not shown.

View File

@ -0,0 +1,905 @@
{
"runtimeTarget": {
"name": ".NETCoreApp,Version=v8.0",
"signature": ""
},
"compilationOptions": {},
"targets": {
".NETCoreApp,Version=v8.0": {
"renis-backend/1.0.0": {
"dependencies": {
"Faker.Net": "2.0.163",
"Microsoft.AspNetCore.OpenApi": "8.0.8",
"Microsoft.EntityFrameworkCore": "8.0.8",
"Npgsql.EntityFrameworkCore.PostgreSQL": "8.0.4",
"Serilog": "4.0.0",
"Serilog.AspNetCore": "8.0.1",
"Serilog.Enrichers.Environment": "2.3.0",
"Serilog.Exceptions": "8.4.0",
"Serilog.Extensions.Logging": "8.0.0",
"Serilog.Formatting.OpenSearch": "1.0.0",
"Serilog.Sinks.Console": "5.0.1",
"Serilog.Sinks.Debug": "2.0.0",
"Serilog.Sinks.File": "5.0.0",
"Serilog.Sinks.OpenSearch": "1.0.0",
"Swashbuckle.AspNetCore": "6.7.3",
"System.IdentityModel.Tokens.Jwt": "8.0.2"
},
"runtime": {
"renis-backend.dll": {}
}
},
"Faker.Net/2.0.163": {
"dependencies": {
"NETStandard.Library": "2.0.3"
},
"runtime": {
"lib/net60/Faker.Net.6.0.dll": {
"assemblyVersion": "2.0.163.0",
"fileVersion": "2.0.163.0"
}
},
"resources": {
"lib/net60/de-DE/Faker.Net.6.0.resources.dll": {
"locale": "de-DE"
}
}
},
"Microsoft.AspNetCore.OpenApi/8.0.8": {
"dependencies": {
"Microsoft.OpenApi": "1.6.14"
},
"runtime": {
"lib/net8.0/Microsoft.AspNetCore.OpenApi.dll": {
"assemblyVersion": "8.0.8.0",
"fileVersion": "8.0.824.36908"
}
}
},
"Microsoft.CSharp/4.6.0": {},
"Microsoft.EntityFrameworkCore/8.0.8": {
"dependencies": {
"Microsoft.EntityFrameworkCore.Abstractions": "8.0.8",
"Microsoft.EntityFrameworkCore.Analyzers": "8.0.8",
"Microsoft.Extensions.Caching.Memory": "8.0.0",
"Microsoft.Extensions.Logging": "8.0.0"
},
"runtime": {
"lib/net8.0/Microsoft.EntityFrameworkCore.dll": {
"assemblyVersion": "8.0.8.0",
"fileVersion": "8.0.824.36704"
}
}
},
"Microsoft.EntityFrameworkCore.Abstractions/8.0.8": {
"runtime": {
"lib/net8.0/Microsoft.EntityFrameworkCore.Abstractions.dll": {
"assemblyVersion": "8.0.8.0",
"fileVersion": "8.0.824.36704"
}
}
},
"Microsoft.EntityFrameworkCore.Analyzers/8.0.8": {},
"Microsoft.EntityFrameworkCore.Relational/8.0.4": {
"dependencies": {
"Microsoft.EntityFrameworkCore": "8.0.8",
"Microsoft.Extensions.Configuration.Abstractions": "8.0.0"
},
"runtime": {
"lib/net8.0/Microsoft.EntityFrameworkCore.Relational.dll": {
"assemblyVersion": "8.0.4.0",
"fileVersion": "8.0.424.16902"
}
}
},
"Microsoft.Extensions.ApiDescription.Server/6.0.5": {},
"Microsoft.Extensions.Caching.Abstractions/8.0.0": {
"dependencies": {
"Microsoft.Extensions.Primitives": "8.0.0"
}
},
"Microsoft.Extensions.Caching.Memory/8.0.0": {
"dependencies": {
"Microsoft.Extensions.Caching.Abstractions": "8.0.0",
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0",
"Microsoft.Extensions.Logging.Abstractions": "8.0.0",
"Microsoft.Extensions.Options": "8.0.0",
"Microsoft.Extensions.Primitives": "8.0.0"
}
},
"Microsoft.Extensions.Configuration.Abstractions/8.0.0": {
"dependencies": {
"Microsoft.Extensions.Primitives": "8.0.0"
}
},
"Microsoft.Extensions.Configuration.Binder/8.0.0": {
"dependencies": {
"Microsoft.Extensions.Configuration.Abstractions": "8.0.0"
}
},
"Microsoft.Extensions.DependencyInjection/8.0.0": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions/8.0.0": {},
"Microsoft.Extensions.DependencyModel/8.0.0": {
"dependencies": {
"System.Text.Encodings.Web": "8.0.0",
"System.Text.Json": "8.0.0"
},
"runtime": {
"lib/net8.0/Microsoft.Extensions.DependencyModel.dll": {
"assemblyVersion": "8.0.0.0",
"fileVersion": "8.0.23.53103"
}
}
},
"Microsoft.Extensions.Diagnostics.Abstractions/8.0.0": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0",
"Microsoft.Extensions.Options": "8.0.0",
"System.Diagnostics.DiagnosticSource": "8.0.0"
}
},
"Microsoft.Extensions.FileProviders.Abstractions/8.0.0": {
"dependencies": {
"Microsoft.Extensions.Primitives": "8.0.0"
}
},
"Microsoft.Extensions.Hosting.Abstractions/8.0.0": {
"dependencies": {
"Microsoft.Extensions.Configuration.Abstractions": "8.0.0",
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0",
"Microsoft.Extensions.Diagnostics.Abstractions": "8.0.0",
"Microsoft.Extensions.FileProviders.Abstractions": "8.0.0",
"Microsoft.Extensions.Logging.Abstractions": "8.0.0"
}
},
"Microsoft.Extensions.Logging/8.0.0": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "8.0.0",
"Microsoft.Extensions.Logging.Abstractions": "8.0.0",
"Microsoft.Extensions.Options": "8.0.0"
}
},
"Microsoft.Extensions.Logging.Abstractions/8.0.0": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0"
}
},
"Microsoft.Extensions.Options/8.0.0": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0",
"Microsoft.Extensions.Primitives": "8.0.0"
}
},
"Microsoft.Extensions.Primitives/8.0.0": {},
"Microsoft.IdentityModel.Abstractions/8.0.2": {
"runtime": {
"lib/net8.0/Microsoft.IdentityModel.Abstractions.dll": {
"assemblyVersion": "8.0.2.0",
"fileVersion": "8.0.2.50822"
}
}
},
"Microsoft.IdentityModel.JsonWebTokens/8.0.2": {
"dependencies": {
"Microsoft.IdentityModel.Tokens": "8.0.2"
},
"runtime": {
"lib/net8.0/Microsoft.IdentityModel.JsonWebTokens.dll": {
"assemblyVersion": "8.0.2.0",
"fileVersion": "8.0.2.50822"
}
}
},
"Microsoft.IdentityModel.Logging/8.0.2": {
"dependencies": {
"Microsoft.IdentityModel.Abstractions": "8.0.2"
},
"runtime": {
"lib/net8.0/Microsoft.IdentityModel.Logging.dll": {
"assemblyVersion": "8.0.2.0",
"fileVersion": "8.0.2.50822"
}
}
},
"Microsoft.IdentityModel.Tokens/8.0.2": {
"dependencies": {
"Microsoft.IdentityModel.Logging": "8.0.2"
},
"runtime": {
"lib/net8.0/Microsoft.IdentityModel.Tokens.dll": {
"assemblyVersion": "8.0.2.0",
"fileVersion": "8.0.2.50822"
}
}
},
"Microsoft.NETCore.Platforms/1.1.0": {},
"Microsoft.OpenApi/1.6.14": {
"runtime": {
"lib/netstandard2.0/Microsoft.OpenApi.dll": {
"assemblyVersion": "1.6.14.0",
"fileVersion": "1.6.14.0"
}
}
},
"NETStandard.Library/2.0.3": {
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0"
}
},
"Npgsql/8.0.3": {
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "8.0.0"
},
"runtime": {
"lib/net8.0/Npgsql.dll": {
"assemblyVersion": "8.0.3.0",
"fileVersion": "8.0.3.0"
}
}
},
"Npgsql.EntityFrameworkCore.PostgreSQL/8.0.4": {
"dependencies": {
"Microsoft.EntityFrameworkCore": "8.0.8",
"Microsoft.EntityFrameworkCore.Abstractions": "8.0.8",
"Microsoft.EntityFrameworkCore.Relational": "8.0.4",
"Npgsql": "8.0.3"
},
"runtime": {
"lib/net8.0/Npgsql.EntityFrameworkCore.PostgreSQL.dll": {
"assemblyVersion": "8.0.4.0",
"fileVersion": "8.0.4.0"
}
}
},
"OpenSearch.Net/1.2.0": {
"dependencies": {
"Microsoft.CSharp": "4.6.0",
"System.Buffers": "4.5.1",
"System.Diagnostics.DiagnosticSource": "8.0.0"
},
"runtime": {
"lib/netstandard2.1/OpenSearch.Net.dll": {
"assemblyVersion": "1.2.0.0",
"fileVersion": "1.2.0.0"
}
}
},
"Serilog/4.0.0": {
"runtime": {
"lib/net8.0/Serilog.dll": {
"assemblyVersion": "4.0.0.0",
"fileVersion": "4.0.0.0"
}
}
},
"Serilog.AspNetCore/8.0.1": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "8.0.0",
"Microsoft.Extensions.Logging": "8.0.0",
"Serilog": "4.0.0",
"Serilog.Extensions.Hosting": "8.0.0",
"Serilog.Extensions.Logging": "8.0.0",
"Serilog.Formatting.Compact": "2.0.0",
"Serilog.Settings.Configuration": "8.0.0",
"Serilog.Sinks.Console": "5.0.1",
"Serilog.Sinks.Debug": "2.0.0",
"Serilog.Sinks.File": "5.0.0"
},
"runtime": {
"lib/net8.0/Serilog.AspNetCore.dll": {
"assemblyVersion": "8.0.1.0",
"fileVersion": "8.0.1.0"
}
}
},
"Serilog.Enrichers.Environment/2.3.0": {
"dependencies": {
"Serilog": "4.0.0"
},
"runtime": {
"lib/netstandard2.0/Serilog.Enrichers.Environment.dll": {
"assemblyVersion": "2.0.0.0",
"fileVersion": "2.3.0.0"
}
}
},
"Serilog.Exceptions/8.4.0": {
"dependencies": {
"Serilog": "4.0.0",
"System.Reflection.TypeExtensions": "4.7.0"
},
"runtime": {
"lib/net6.0/Serilog.Exceptions.dll": {
"assemblyVersion": "8.0.0.0",
"fileVersion": "8.4.0.0"
}
}
},
"Serilog.Extensions.Hosting/8.0.0": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0",
"Microsoft.Extensions.Hosting.Abstractions": "8.0.0",
"Microsoft.Extensions.Logging.Abstractions": "8.0.0",
"Serilog": "4.0.0",
"Serilog.Extensions.Logging": "8.0.0"
},
"runtime": {
"lib/net8.0/Serilog.Extensions.Hosting.dll": {
"assemblyVersion": "7.0.0.0",
"fileVersion": "8.0.0.0"
}
}
},
"Serilog.Extensions.Logging/8.0.0": {
"dependencies": {
"Microsoft.Extensions.Logging": "8.0.0",
"Serilog": "4.0.0"
},
"runtime": {
"lib/net8.0/Serilog.Extensions.Logging.dll": {
"assemblyVersion": "7.0.0.0",
"fileVersion": "8.0.0.0"
}
}
},
"Serilog.Formatting.Compact/2.0.0": {
"dependencies": {
"Serilog": "4.0.0"
},
"runtime": {
"lib/net7.0/Serilog.Formatting.Compact.dll": {
"assemblyVersion": "2.0.0.0",
"fileVersion": "2.0.0.0"
}
}
},
"Serilog.Formatting.OpenSearch/1.0.0": {
"dependencies": {
"Serilog": "4.0.0"
},
"runtime": {
"lib/netstandard2.0/Serilog.Formatting.OpenSearch.dll": {
"assemblyVersion": "1.0.0.0",
"fileVersion": "1.0.0.0"
}
}
},
"Serilog.Settings.Configuration/8.0.0": {
"dependencies": {
"Microsoft.Extensions.Configuration.Binder": "8.0.0",
"Microsoft.Extensions.DependencyModel": "8.0.0",
"Serilog": "4.0.0"
},
"runtime": {
"lib/net8.0/Serilog.Settings.Configuration.dll": {
"assemblyVersion": "8.0.0.0",
"fileVersion": "8.0.0.0"
}
}
},
"Serilog.Sinks.Console/5.0.1": {
"dependencies": {
"Serilog": "4.0.0"
},
"runtime": {
"lib/net7.0/Serilog.Sinks.Console.dll": {
"assemblyVersion": "5.0.1.0",
"fileVersion": "5.0.1.0"
}
}
},
"Serilog.Sinks.Debug/2.0.0": {
"dependencies": {
"Serilog": "4.0.0"
},
"runtime": {
"lib/netstandard2.1/Serilog.Sinks.Debug.dll": {
"assemblyVersion": "2.0.0.0",
"fileVersion": "2.0.0.0"
}
}
},
"Serilog.Sinks.File/5.0.0": {
"dependencies": {
"Serilog": "4.0.0"
},
"runtime": {
"lib/net5.0/Serilog.Sinks.File.dll": {
"assemblyVersion": "5.0.0.0",
"fileVersion": "5.0.0.0"
}
}
},
"Serilog.Sinks.OpenSearch/1.0.0": {
"dependencies": {
"OpenSearch.Net": "1.2.0",
"Serilog": "4.0.0",
"Serilog.Formatting.Compact": "2.0.0",
"Serilog.Formatting.OpenSearch": "1.0.0",
"Serilog.Sinks.File": "5.0.0",
"Serilog.Sinks.PeriodicBatching": "3.1.0",
"System.Diagnostics.DiagnosticSource": "8.0.0"
},
"runtime": {
"lib/netstandard2.0/Serilog.Sinks.OpenSearch.dll": {
"assemblyVersion": "1.0.0.0",
"fileVersion": "1.0.0.0"
}
}
},
"Serilog.Sinks.PeriodicBatching/3.1.0": {
"dependencies": {
"Serilog": "4.0.0"
},
"runtime": {
"lib/netstandard2.1/Serilog.Sinks.PeriodicBatching.dll": {
"assemblyVersion": "3.0.0.0",
"fileVersion": "3.1.0.0"
}
}
},
"Swashbuckle.AspNetCore/6.7.3": {
"dependencies": {
"Microsoft.Extensions.ApiDescription.Server": "6.0.5",
"Swashbuckle.AspNetCore.Swagger": "6.7.3",
"Swashbuckle.AspNetCore.SwaggerGen": "6.7.3",
"Swashbuckle.AspNetCore.SwaggerUI": "6.7.3"
}
},
"Swashbuckle.AspNetCore.Swagger/6.7.3": {
"dependencies": {
"Microsoft.OpenApi": "1.6.14"
},
"runtime": {
"lib/net8.0/Swashbuckle.AspNetCore.Swagger.dll": {
"assemblyVersion": "6.7.3.0",
"fileVersion": "6.7.3.685"
}
}
},
"Swashbuckle.AspNetCore.SwaggerGen/6.7.3": {
"dependencies": {
"Swashbuckle.AspNetCore.Swagger": "6.7.3"
},
"runtime": {
"lib/net8.0/Swashbuckle.AspNetCore.SwaggerGen.dll": {
"assemblyVersion": "6.7.3.0",
"fileVersion": "6.7.3.685"
}
}
},
"Swashbuckle.AspNetCore.SwaggerUI/6.7.3": {
"runtime": {
"lib/net8.0/Swashbuckle.AspNetCore.SwaggerUI.dll": {
"assemblyVersion": "6.7.3.0",
"fileVersion": "6.7.3.685"
}
}
},
"System.Buffers/4.5.1": {},
"System.Diagnostics.DiagnosticSource/8.0.0": {},
"System.IdentityModel.Tokens.Jwt/8.0.2": {
"dependencies": {
"Microsoft.IdentityModel.JsonWebTokens": "8.0.2",
"Microsoft.IdentityModel.Tokens": "8.0.2"
},
"runtime": {
"lib/net8.0/System.IdentityModel.Tokens.Jwt.dll": {
"assemblyVersion": "8.0.2.0",
"fileVersion": "8.0.2.50822"
}
}
},
"System.Reflection.TypeExtensions/4.7.0": {},
"System.Text.Encodings.Web/8.0.0": {},
"System.Text.Json/8.0.0": {
"dependencies": {
"System.Text.Encodings.Web": "8.0.0"
}
}
}
},
"libraries": {
"renis-backend/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Faker.Net/2.0.163": {
"type": "package",
"serviceable": true,
"sha512": "sha512-nQZA+V19Jf6tSeFnuRWpoVZzSHRmtfOYAnX5RbkY6+HBHpLg55DYTnxUSXeFHpmsgQzmkjG7Ucomk7FisJnfhA==",
"path": "faker.net/2.0.163",
"hashPath": "faker.net.2.0.163.nupkg.sha512"
},
"Microsoft.AspNetCore.OpenApi/8.0.8": {
"type": "package",
"serviceable": true,
"sha512": "sha512-wNHhohqP8rmsQ4UhKbd6jZMD6l+2Q/+DvRBT0Cgqeuglr13aF6sSJWicZKCIhZAUXzuhkdwtHVc95MlPlFk0dA==",
"path": "microsoft.aspnetcore.openapi/8.0.8",
"hashPath": "microsoft.aspnetcore.openapi.8.0.8.nupkg.sha512"
},
"Microsoft.CSharp/4.6.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-kxn3M2rnAGy5N5DgcIwcE8QTePWU/XiYcQVzn9HqTls2NKluVzVSmVWRjK7OUPWbljCXuZxHyhEz9kPRIQeXow==",
"path": "microsoft.csharp/4.6.0",
"hashPath": "microsoft.csharp.4.6.0.nupkg.sha512"
},
"Microsoft.EntityFrameworkCore/8.0.8": {
"type": "package",
"serviceable": true,
"sha512": "sha512-iK+jrJzkfbIxutB7or808BPmJtjUEi5O+eSM7cLDwsyde6+3iOujCSfWnrHrLxY3u+EQrJD+aD8DJ6ogPA2Rtw==",
"path": "microsoft.entityframeworkcore/8.0.8",
"hashPath": "microsoft.entityframeworkcore.8.0.8.nupkg.sha512"
},
"Microsoft.EntityFrameworkCore.Abstractions/8.0.8": {
"type": "package",
"serviceable": true,
"sha512": "sha512-9mMQkZsfL1c2iifBD8MWRmwy59rvsVtR9NOezJj7+g1j4P7g49MJHd8k8faC/v7d5KuHkQ6KOQiSItvoRt9PXA==",
"path": "microsoft.entityframeworkcore.abstractions/8.0.8",
"hashPath": "microsoft.entityframeworkcore.abstractions.8.0.8.nupkg.sha512"
},
"Microsoft.EntityFrameworkCore.Analyzers/8.0.8": {
"type": "package",
"serviceable": true,
"sha512": "sha512-OlAXMU+VQgLz5y5/SBkLvAa9VeiR3dlJqgIebEEH2M2NGA3evm68/Tv7SLWmSxwnEAtA3nmDEZF2pacK6eXh4Q==",
"path": "microsoft.entityframeworkcore.analyzers/8.0.8",
"hashPath": "microsoft.entityframeworkcore.analyzers.8.0.8.nupkg.sha512"
},
"Microsoft.EntityFrameworkCore.Relational/8.0.4": {
"type": "package",
"serviceable": true,
"sha512": "sha512-aWLT6e9a8oMzXgF0YQpYYa3mDeU+yb2UQSQ+RrIgyGgSpzPfSKgpA7v2kOVDuZr2AQ6NNAlWPaBG7wZuKQI96w==",
"path": "microsoft.entityframeworkcore.relational/8.0.4",
"hashPath": "microsoft.entityframeworkcore.relational.8.0.4.nupkg.sha512"
},
"Microsoft.Extensions.ApiDescription.Server/6.0.5": {
"type": "package",
"serviceable": true,
"sha512": "sha512-Ckb5EDBUNJdFWyajfXzUIMRkhf52fHZOQuuZg/oiu8y7zDCVwD0iHhew6MnThjHmevanpxL3f5ci2TtHQEN6bw==",
"path": "microsoft.extensions.apidescription.server/6.0.5",
"hashPath": "microsoft.extensions.apidescription.server.6.0.5.nupkg.sha512"
},
"Microsoft.Extensions.Caching.Abstractions/8.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-3KuSxeHoNYdxVYfg2IRZCThcrlJ1XJqIXkAWikCsbm5C/bCjv7G0WoKDyuR98Q+T607QT2Zl5GsbGRkENcV2yQ==",
"path": "microsoft.extensions.caching.abstractions/8.0.0",
"hashPath": "microsoft.extensions.caching.abstractions.8.0.0.nupkg.sha512"
},
"Microsoft.Extensions.Caching.Memory/8.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-7pqivmrZDzo1ADPkRwjy+8jtRKWRCPag9qPI+p7sgu7Q4QreWhcvbiWXsbhP+yY8XSiDvZpu2/LWdBv7PnmOpQ==",
"path": "microsoft.extensions.caching.memory/8.0.0",
"hashPath": "microsoft.extensions.caching.memory.8.0.0.nupkg.sha512"
},
"Microsoft.Extensions.Configuration.Abstractions/8.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-3lE/iLSutpgX1CC0NOW70FJoGARRHbyKmG7dc0klnUZ9Dd9hS6N/POPWhKhMLCEuNN5nXEY5agmlFtH562vqhQ==",
"path": "microsoft.extensions.configuration.abstractions/8.0.0",
"hashPath": "microsoft.extensions.configuration.abstractions.8.0.0.nupkg.sha512"
},
"Microsoft.Extensions.Configuration.Binder/8.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-mBMoXLsr5s1y2zOHWmKsE9veDcx8h1x/c3rz4baEdQKTeDcmQAPNbB54Pi/lhFO3K431eEq6PFbMgLaa6PHFfA==",
"path": "microsoft.extensions.configuration.binder/8.0.0",
"hashPath": "microsoft.extensions.configuration.binder.8.0.0.nupkg.sha512"
},
"Microsoft.Extensions.DependencyInjection/8.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-V8S3bsm50ig6JSyrbcJJ8bW2b9QLGouz+G1miK3UTaOWmMtFwNNNzUf4AleyDWUmTrWMLNnFSLEQtxmxgNQnNQ==",
"path": "microsoft.extensions.dependencyinjection/8.0.0",
"hashPath": "microsoft.extensions.dependencyinjection.8.0.0.nupkg.sha512"
},
"Microsoft.Extensions.DependencyInjection.Abstractions/8.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-cjWrLkJXK0rs4zofsK4bSdg+jhDLTaxrkXu4gS6Y7MAlCvRyNNgwY/lJi5RDlQOnSZweHqoyvgvbdvQsRIW+hg==",
"path": "microsoft.extensions.dependencyinjection.abstractions/8.0.0",
"hashPath": "microsoft.extensions.dependencyinjection.abstractions.8.0.0.nupkg.sha512"
},
"Microsoft.Extensions.DependencyModel/8.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-NSmDw3K0ozNDgShSIpsZcbFIzBX4w28nDag+TfaQujkXGazBm+lid5onlWoCBy4VsLxqnnKjEBbGSJVWJMf43g==",
"path": "microsoft.extensions.dependencymodel/8.0.0",
"hashPath": "microsoft.extensions.dependencymodel.8.0.0.nupkg.sha512"
},
"Microsoft.Extensions.Diagnostics.Abstractions/8.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-JHYCQG7HmugNYUhOl368g+NMxYE/N/AiclCYRNlgCY9eVyiBkOHMwK4x60RYMxv9EL3+rmj1mqHvdCiPpC+D4Q==",
"path": "microsoft.extensions.diagnostics.abstractions/8.0.0",
"hashPath": "microsoft.extensions.diagnostics.abstractions.8.0.0.nupkg.sha512"
},
"Microsoft.Extensions.FileProviders.Abstractions/8.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-ZbaMlhJlpisjuWbvXr4LdAst/1XxH3vZ6A0BsgTphZ2L4PGuxRLz7Jr/S7mkAAnOn78Vu0fKhEgNF5JO3zfjqQ==",
"path": "microsoft.extensions.fileproviders.abstractions/8.0.0",
"hashPath": "microsoft.extensions.fileproviders.abstractions.8.0.0.nupkg.sha512"
},
"Microsoft.Extensions.Hosting.Abstractions/8.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-AG7HWwVRdCHlaA++1oKDxLsXIBxmDpMPb3VoyOoAghEWnkUvEAdYQUwnV4jJbAaa/nMYNiEh5ByoLauZBEiovg==",
"path": "microsoft.extensions.hosting.abstractions/8.0.0",
"hashPath": "microsoft.extensions.hosting.abstractions.8.0.0.nupkg.sha512"
},
"Microsoft.Extensions.Logging/8.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-tvRkov9tAJ3xP51LCv3FJ2zINmv1P8Hi8lhhtcKGqM+ImiTCC84uOPEI4z8Cdq2C3o9e+Aa0Gw0rmrsJD77W+w==",
"path": "microsoft.extensions.logging/8.0.0",
"hashPath": "microsoft.extensions.logging.8.0.0.nupkg.sha512"
},
"Microsoft.Extensions.Logging.Abstractions/8.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-arDBqTgFCyS0EvRV7O3MZturChstm50OJ0y9bDJvAcmEPJm0FFpFyjU/JLYyStNGGey081DvnQYlncNX5SJJGA==",
"path": "microsoft.extensions.logging.abstractions/8.0.0",
"hashPath": "microsoft.extensions.logging.abstractions.8.0.0.nupkg.sha512"
},
"Microsoft.Extensions.Options/8.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-JOVOfqpnqlVLUzINQ2fox8evY2SKLYJ3BV8QDe/Jyp21u1T7r45x/R/5QdteURMR5r01GxeJSBBUOCOyaNXA3g==",
"path": "microsoft.extensions.options/8.0.0",
"hashPath": "microsoft.extensions.options.8.0.0.nupkg.sha512"
},
"Microsoft.Extensions.Primitives/8.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-bXJEZrW9ny8vjMF1JV253WeLhpEVzFo1lyaZu1vQ4ZxWUlVvknZ/+ftFgVheLubb4eZPSwwxBeqS1JkCOjxd8g==",
"path": "microsoft.extensions.primitives/8.0.0",
"hashPath": "microsoft.extensions.primitives.8.0.0.nupkg.sha512"
},
"Microsoft.IdentityModel.Abstractions/8.0.2": {
"type": "package",
"serviceable": true,
"sha512": "sha512-m73Bun0l0jL8rceWZ9TMD4hwQCjDIaRT1s5RMN7TBDpXu8Ea8KcRndo45btW9gG0i/USmHLCmOBIITvTA4Y6PA==",
"path": "microsoft.identitymodel.abstractions/8.0.2",
"hashPath": "microsoft.identitymodel.abstractions.8.0.2.nupkg.sha512"
},
"Microsoft.IdentityModel.JsonWebTokens/8.0.2": {
"type": "package",
"serviceable": true,
"sha512": "sha512-6CVWMfXrQPMUaqlsMfG8OjtyTIKvtgiQCFOJ2YhSZo1UDaAWweVN7jGSrz59Ez0Y8lh260WE5V2b0Oe9NlVlyw==",
"path": "microsoft.identitymodel.jsonwebtokens/8.0.2",
"hashPath": "microsoft.identitymodel.jsonwebtokens.8.0.2.nupkg.sha512"
},
"Microsoft.IdentityModel.Logging/8.0.2": {
"type": "package",
"serviceable": true,
"sha512": "sha512-iKUyFKCQgc8rcEqyIJGLOIqqxemG7bgraqS9n5J6RPoZZH7dwxmJd3aFYmxXuAnfznJuaE1DQX5U46Cqvb+BOg==",
"path": "microsoft.identitymodel.logging/8.0.2",
"hashPath": "microsoft.identitymodel.logging.8.0.2.nupkg.sha512"
},
"Microsoft.IdentityModel.Tokens/8.0.2": {
"type": "package",
"serviceable": true,
"sha512": "sha512-X58KyDBpGJZcCfmSgbkxJLLxd04eMFVaJlMEbRCyWL1X44n6kMxRyK6UTS1zgi5DHikeyiZj8bi7+p0kfPepLg==",
"path": "microsoft.identitymodel.tokens/8.0.2",
"hashPath": "microsoft.identitymodel.tokens.8.0.2.nupkg.sha512"
},
"Microsoft.NETCore.Platforms/1.1.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A==",
"path": "microsoft.netcore.platforms/1.1.0",
"hashPath": "microsoft.netcore.platforms.1.1.0.nupkg.sha512"
},
"Microsoft.OpenApi/1.6.14": {
"type": "package",
"serviceable": true,
"sha512": "sha512-tTaBT8qjk3xINfESyOPE2rIellPvB7qpVqiWiyA/lACVvz+xOGiXhFUfohcx82NLbi5avzLW0lx+s6oAqQijfw==",
"path": "microsoft.openapi/1.6.14",
"hashPath": "microsoft.openapi.1.6.14.nupkg.sha512"
},
"NETStandard.Library/2.0.3": {
"type": "package",
"serviceable": true,
"sha512": "sha512-st47PosZSHrjECdjeIzZQbzivYBJFv6P2nv4cj2ypdI204DO+vZ7l5raGMiX4eXMJ53RfOIg+/s4DHVZ54Nu2A==",
"path": "netstandard.library/2.0.3",
"hashPath": "netstandard.library.2.0.3.nupkg.sha512"
},
"Npgsql/8.0.3": {
"type": "package",
"serviceable": true,
"sha512": "sha512-6WEmzsQJCZAlUG1pThKg/RmeF6V+I0DmBBBE/8YzpRtEzhyZzKcK7ulMANDm5CkxrALBEC8H+5plxHWtIL7xnA==",
"path": "npgsql/8.0.3",
"hashPath": "npgsql.8.0.3.nupkg.sha512"
},
"Npgsql.EntityFrameworkCore.PostgreSQL/8.0.4": {
"type": "package",
"serviceable": true,
"sha512": "sha512-/hHd9MqTRVDgIpsToCcxMDxZqla0HAQACiITkq1+L9J2hmHKV6lBAPlauF+dlNSfHpus7rrljWx4nAanKD6qAw==",
"path": "npgsql.entityframeworkcore.postgresql/8.0.4",
"hashPath": "npgsql.entityframeworkcore.postgresql.8.0.4.nupkg.sha512"
},
"OpenSearch.Net/1.2.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-eawNOvFa4F7QP2Fg7o8e3RP99ThdsPhRG1HijwK3V7p/7VA0xXd+8lfY6F8igQDIfgoLb7/8tYPyh35jEX8VKw==",
"path": "opensearch.net/1.2.0",
"hashPath": "opensearch.net.1.2.0.nupkg.sha512"
},
"Serilog/4.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-2jDkUrSh5EofOp7Lx5Zgy0EB+7hXjjxE2ktTb1WVQmU00lDACR2TdROGKU0K1pDTBSJBN1PqgYpgOZF8mL7NJw==",
"path": "serilog/4.0.0",
"hashPath": "serilog.4.0.0.nupkg.sha512"
},
"Serilog.AspNetCore/8.0.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-B/X+wAfS7yWLVOTD83B+Ip9yl4MkhioaXj90JSoWi1Ayi8XHepEnsBdrkojg08eodCnmOKmShFUN2GgEc6c0CQ==",
"path": "serilog.aspnetcore/8.0.1",
"hashPath": "serilog.aspnetcore.8.0.1.nupkg.sha512"
},
"Serilog.Enrichers.Environment/2.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-AdZXURQ0dQCCjst3Jn3lwFtGicWjGE4wov9E5BPc4N5cruGmd2y9wprCYEjFteU84QMbxk35fpeTuHs6M4VGYw==",
"path": "serilog.enrichers.environment/2.3.0",
"hashPath": "serilog.enrichers.environment.2.3.0.nupkg.sha512"
},
"Serilog.Exceptions/8.4.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-nc/+hUw3lsdo0zCj0KMIybAu7perMx79vu72w0za9Nsi6mWyNkGXxYxakAjWB7nEmYL6zdmhEQRB4oJ2ALUeug==",
"path": "serilog.exceptions/8.4.0",
"hashPath": "serilog.exceptions.8.4.0.nupkg.sha512"
},
"Serilog.Extensions.Hosting/8.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-db0OcbWeSCvYQkHWu6n0v40N4kKaTAXNjlM3BKvcbwvNzYphQFcBR+36eQ/7hMMwOkJvAyLC2a9/jNdUL5NjtQ==",
"path": "serilog.extensions.hosting/8.0.0",
"hashPath": "serilog.extensions.hosting.8.0.0.nupkg.sha512"
},
"Serilog.Extensions.Logging/8.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-YEAMWu1UnWgf1c1KP85l1SgXGfiVo0Rz6x08pCiPOIBt2Qe18tcZLvdBUuV5o1QHvrs8FAry9wTIhgBRtjIlEg==",
"path": "serilog.extensions.logging/8.0.0",
"hashPath": "serilog.extensions.logging.8.0.0.nupkg.sha512"
},
"Serilog.Formatting.Compact/2.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-ob6z3ikzFM3D1xalhFuBIK1IOWf+XrQq+H4KeH4VqBcPpNcmUgZlRQ2h3Q7wvthpdZBBoY86qZOI2LCXNaLlNA==",
"path": "serilog.formatting.compact/2.0.0",
"hashPath": "serilog.formatting.compact.2.0.0.nupkg.sha512"
},
"Serilog.Formatting.OpenSearch/1.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-RO8aEB6uzZEUmgE7MSwyVtevutAuXsk9b2BeKoH/Mq4Ns8U7gKdTEgSRkZdVYFY5XyrcLIOUlieXqmcjgpBFnA==",
"path": "serilog.formatting.opensearch/1.0.0",
"hashPath": "serilog.formatting.opensearch.1.0.0.nupkg.sha512"
},
"Serilog.Settings.Configuration/8.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-nR0iL5HwKj5v6ULo3/zpP8NMcq9E2pxYA6XKTSWCbugVs4YqPyvaqaKOY+OMpPivKp7zMEpax2UKHnDodbRB0Q==",
"path": "serilog.settings.configuration/8.0.0",
"hashPath": "serilog.settings.configuration.8.0.0.nupkg.sha512"
},
"Serilog.Sinks.Console/5.0.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-6Jt8jl9y2ey8VV7nVEUAyjjyxjAQuvd5+qj4XYAT9CwcsvR70HHULGBeD+K2WCALFXf7CFsNQT4lON6qXcu2AA==",
"path": "serilog.sinks.console/5.0.1",
"hashPath": "serilog.sinks.console.5.0.1.nupkg.sha512"
},
"Serilog.Sinks.Debug/2.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-Y6g3OBJ4JzTyyw16fDqtFcQ41qQAydnEvEqmXjhwhgjsnG/FaJ8GUqF5ldsC/bVkK8KYmqrPhDO+tm4dF6xx4A==",
"path": "serilog.sinks.debug/2.0.0",
"hashPath": "serilog.sinks.debug.2.0.0.nupkg.sha512"
},
"Serilog.Sinks.File/5.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-uwV5hdhWPwUH1szhO8PJpFiahqXmzPzJT/sOijH/kFgUx+cyoDTMM8MHD0adw9+Iem6itoibbUXHYslzXsLEAg==",
"path": "serilog.sinks.file/5.0.0",
"hashPath": "serilog.sinks.file.5.0.0.nupkg.sha512"
},
"Serilog.Sinks.OpenSearch/1.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-OyHVgttWqlkcD5Fd06aFztfT/IzM23kIabW9ovYT4gVNuhI+WO7iYA8dIiEslyqeABG71toTaN3LeVG0H9FgYQ==",
"path": "serilog.sinks.opensearch/1.0.0",
"hashPath": "serilog.sinks.opensearch.1.0.0.nupkg.sha512"
},
"Serilog.Sinks.PeriodicBatching/3.1.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-NDWR7m3PalVlGEq3rzoktrXikjFMLmpwF0HI4sowo8YDdU+gqPlTHlDQiOGxHfB0sTfjPA9JjA7ctKG9zqjGkw==",
"path": "serilog.sinks.periodicbatching/3.1.0",
"hashPath": "serilog.sinks.periodicbatching.3.1.0.nupkg.sha512"
},
"Swashbuckle.AspNetCore/6.7.3": {
"type": "package",
"serviceable": true,
"sha512": "sha512-PYTm/M5YrkEUHmguhj6vF1DshG2deKMMcsnhKet1BkcKzZHNX/VVQady0T/jNpXrtxhLR3vB10hWhONF1Nbglw==",
"path": "swashbuckle.aspnetcore/6.7.3",
"hashPath": "swashbuckle.aspnetcore.6.7.3.nupkg.sha512"
},
"Swashbuckle.AspNetCore.Swagger/6.7.3": {
"type": "package",
"serviceable": true,
"sha512": "sha512-plNVrOpup/UCIP0aSE5cznIzXMC17EOOqIceWqhP829evEAUwTomCc+1TPy2xK2E+OilYcYEdUus3rOUMjjm/g==",
"path": "swashbuckle.aspnetcore.swagger/6.7.3",
"hashPath": "swashbuckle.aspnetcore.swagger.6.7.3.nupkg.sha512"
},
"Swashbuckle.AspNetCore.SwaggerGen/6.7.3": {
"type": "package",
"serviceable": true,
"sha512": "sha512-kvjGd+g85YFZqyEQZSBUCPtEDDCZsiPPYcjgBN6si3C3oik2c9d7Zlq4PIm07pgY/QmBMgyFOVEzHbks6a398w==",
"path": "swashbuckle.aspnetcore.swaggergen/6.7.3",
"hashPath": "swashbuckle.aspnetcore.swaggergen.6.7.3.nupkg.sha512"
},
"Swashbuckle.AspNetCore.SwaggerUI/6.7.3": {
"type": "package",
"serviceable": true,
"sha512": "sha512-exXUT9h++OU70jTCfQALiHzeBthqL7c5IFQm+aa67Hi/6X945t32NtOMO16TaRn44xFXdqMZ2CyMbgnTmx+w2A==",
"path": "swashbuckle.aspnetcore.swaggerui/6.7.3",
"hashPath": "swashbuckle.aspnetcore.swaggerui.6.7.3.nupkg.sha512"
},
"System.Buffers/4.5.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==",
"path": "system.buffers/4.5.1",
"hashPath": "system.buffers.4.5.1.nupkg.sha512"
},
"System.Diagnostics.DiagnosticSource/8.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-c9xLpVz6PL9lp/djOWtk5KPDZq3cSYpmXoJQY524EOtuFl5z9ZtsotpsyrDW40U1DRnQSYvcPKEUV0X//u6gkQ==",
"path": "system.diagnostics.diagnosticsource/8.0.0",
"hashPath": "system.diagnostics.diagnosticsource.8.0.0.nupkg.sha512"
},
"System.IdentityModel.Tokens.Jwt/8.0.2": {
"type": "package",
"serviceable": true,
"sha512": "sha512-jbfANr2qEmrfEtK3L7tOnkCW5/y2YiF6ISSRhRBgIZL+W2ZbEVHFNTNV8QOKeNU6gedQnhpdU2IvB0YB3nNMjw==",
"path": "system.identitymodel.tokens.jwt/8.0.2",
"hashPath": "system.identitymodel.tokens.jwt.8.0.2.nupkg.sha512"
},
"System.Reflection.TypeExtensions/4.7.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-VybpaOQQhqE6siHppMktjfGBw1GCwvCqiufqmP8F1nj7fTUNtW35LOEt3UZTEsECfo+ELAl/9o9nJx3U91i7vA==",
"path": "system.reflection.typeextensions/4.7.0",
"hashPath": "system.reflection.typeextensions.4.7.0.nupkg.sha512"
},
"System.Text.Encodings.Web/8.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-yev/k9GHAEGx2Rg3/tU6MQh4HGBXJs70y7j1LaM1i/ER9po+6nnQ6RRqTJn1E7Xu0fbIFK80Nh5EoODxrbxwBQ==",
"path": "system.text.encodings.web/8.0.0",
"hashPath": "system.text.encodings.web.8.0.0.nupkg.sha512"
},
"System.Text.Json/8.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-OdrZO2WjkiEG6ajEFRABTRCi/wuXQPxeV6g8xvUJqdxMvvuCCEk86zPla8UiIQJz3durtUEbNyY/3lIhS0yZvQ==",
"path": "system.text.json/8.0.0",
"hashPath": "system.text.json.8.0.0.nupkg.sha512"
}
}
}

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,20 @@
{
"runtimeOptions": {
"tfm": "net8.0",
"frameworks": [
{
"name": "Microsoft.NETCore.App",
"version": "8.0.0"
},
{
"name": "Microsoft.AspNetCore.App",
"version": "8.0.0"
}
],
"configProperties": {
"System.GC.Server": true,
"System.Reflection.NullabilityInfoContext.IsSupported": true,
"System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false
}
}
}

View File

@ -8,11 +8,23 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Faker.Net" Version="2.0.163" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.8" /> <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.8" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.7.3" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="6.7.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.8" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.8" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.4" /> <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.4" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.0.2" /> <PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.0.2" />
<PackageReference Include="Serilog" Version="4.0.1" />
<PackageReference Include="Serilog.AspNetCore" Version="8.0.2" />
<PackageReference Include="Serilog.Enrichers.Environment" Version="3.0.1" />
<PackageReference Include="Serilog.Exceptions" Version="8.4.0" />
<PackageReference Include="Serilog.Extensions.Logging" Version="8.0.0" />
<PackageReference Include="Serilog.Formatting.OpenSearch" Version="1.2.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
<PackageReference Include="Serilog.Sinks.Debug" Version="3.0.0" />
<PackageReference Include="Serilog.Sinks.File" Version="6.0.0" />
<PackageReference Include="Serilog.Sinks.OpenSearch" Version="1.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.8" />
</ItemGroup> </ItemGroup>
</Project> </Project>

25
renis-backend.sln Normal file
View File

@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.5.002.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "renis-backend", "renis-backend.csproj", "{9D6F84D2-940C-43B1-862C-263D0D446BCF}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{9D6F84D2-940C-43B1-862C-263D0D446BCF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9D6F84D2-940C-43B1-862C-263D0D446BCF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9D6F84D2-940C-43B1-862C-263D0D446BCF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9D6F84D2-940C-43B1-862C-263D0D446BCF}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {55CAE896-5C10-4114-B9E4-78864BF912A0}
EndGlobalSection
EndGlobal