From d854dbb68cec732b37ce33ba250e084e340e6fb3 Mon Sep 17 00:00:00 2001 From: nikitareshetnik Date: Tue, 9 May 2023 15:52:33 +0300 Subject: [PATCH 01/22] Fixed Swagger UI Operation filter to show lock on endpoints that only requires auth --- AutoHub.API/Extensions/AddSwaggerExtension.cs | 18 ++-------- .../SecurityOperationRequirementsFilter.cs | 36 +++++++++++++++++++ 2 files changed, 39 insertions(+), 15 deletions(-) create mode 100644 AutoHub.API/Filters/SecurityOperationRequirementsFilter.cs diff --git a/AutoHub.API/Extensions/AddSwaggerExtension.cs b/AutoHub.API/Extensions/AddSwaggerExtension.cs index a38096a..d026354 100644 --- a/AutoHub.API/Extensions/AddSwaggerExtension.cs +++ b/AutoHub.API/Extensions/AddSwaggerExtension.cs @@ -3,9 +3,9 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.OpenApi.Models; using System; -using System.Collections.Generic; using System.IO; using System.Reflection; +using AutoHub.API.Filters; namespace AutoHub.API.Extensions; @@ -35,20 +35,8 @@ public static void AddSwagger(this IServiceCollection services) Scheme = JwtBearerDefaults.AuthenticationScheme, BearerFormat = "JWT", }); - c.AddSecurityRequirement(new OpenApiSecurityRequirement - { - { - new OpenApiSecurityScheme - { - Reference = new OpenApiReference - { - Id = JwtBearerDefaults.AuthenticationScheme, - Type = ReferenceType.SecurityScheme - } - }, - new List() - } - }); + + c.OperationFilter(); var xmlFilename = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; c.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFilename)); diff --git a/AutoHub.API/Filters/SecurityOperationRequirementsFilter.cs b/AutoHub.API/Filters/SecurityOperationRequirementsFilter.cs new file mode 100644 index 0000000..27742ac --- /dev/null +++ b/AutoHub.API/Filters/SecurityOperationRequirementsFilter.cs @@ -0,0 +1,36 @@ +using System.Collections.Generic; +using System.Linq; +using Microsoft.AspNetCore.Authentication.JwtBearer; +using Microsoft.AspNetCore.Authorization; +using Microsoft.OpenApi.Models; +using Swashbuckle.AspNetCore.SwaggerGen; + +namespace AutoHub.API.Filters; + +public class SecurityOperationRequirementsFilter : IOperationFilter +{ + public void Apply(OpenApiOperation operation, OperationFilterContext context) + { + if (!context.MethodInfo.GetCustomAttributes(true).Any(x => x is AllowAnonymousAttribute) && + !(context.MethodInfo.DeclaringType?.GetCustomAttributes(true).Any(x => x is AllowAnonymousAttribute) ?? false)) + { + operation.Security = new List + { + new() + { + { + new OpenApiSecurityScheme + { + Reference = new OpenApiReference + { + Id = JwtBearerDefaults.AuthenticationScheme, + Type = ReferenceType.SecurityScheme + } + }, + new List() + } + } + }; + } + } +} \ No newline at end of file From a2e2b8545f7c4ec42c142a5e9a3e1283e2e48152 Mon Sep 17 00:00:00 2001 From: nikitareshetnik Date: Thu, 10 Oct 2024 01:05:31 +0300 Subject: [PATCH 02/22] Added Redoc (Just for fun) + upgraded app to .NET 8 --- AutoHub.API/AutoHub.API.csproj | 4 +++- ...ension.cs => AddDocumentationExtension.cs} | 20 ++++++++++++++++++- AutoHub.API/Program.cs | 3 ++- .../AutoHub.BusinessLogic.csproj | 3 ++- AutoHub.DataAccess/AutoHub.DataAccess.csproj | 3 ++- AutoHub.Domain/AutoHub.Domain.csproj | 3 ++- AutoHub.Tests/AutoHub.Tests.csproj | 4 +++- global.json | 4 ++-- 8 files changed, 35 insertions(+), 9 deletions(-) rename AutoHub.API/Extensions/{AddSwaggerExtension.cs => AddDocumentationExtension.cs} (76%) diff --git a/AutoHub.API/AutoHub.API.csproj b/AutoHub.API/AutoHub.API.csproj index 558723e..1d61242 100644 --- a/AutoHub.API/AutoHub.API.csproj +++ b/AutoHub.API/AutoHub.API.csproj @@ -2,8 +2,9 @@ true - net7.0 + net8.0 d05e2abf-9390-4c8d-8b73-ec1fade60694 + latestmajor @@ -40,6 +41,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/AutoHub.API/Extensions/AddSwaggerExtension.cs b/AutoHub.API/Extensions/AddDocumentationExtension.cs similarity index 76% rename from AutoHub.API/Extensions/AddSwaggerExtension.cs rename to AutoHub.API/Extensions/AddDocumentationExtension.cs index d026354..8f1e036 100644 --- a/AutoHub.API/Extensions/AddSwaggerExtension.cs +++ b/AutoHub.API/Extensions/AddDocumentationExtension.cs @@ -9,7 +9,9 @@ namespace AutoHub.API.Extensions; -public static class AddSwaggerExtension +using Swashbuckle.AspNetCore.ReDoc; + +public static class AddDocumentationExtension { public static void AddSwagger(this IServiceCollection services) { @@ -53,4 +55,20 @@ public static IApplicationBuilder UseSwaggerDocumentation(this IApplicationBuild }); return app; } + + public static IApplicationBuilder UseRedocDocumentation(this IApplicationBuilder app) + { + app.UseReDoc(c => + { + c.SpecUrl("/swagger/v1/swagger.json"); + c.DocumentTitle = "AutoHub.API"; + c.RoutePrefix = "redoc"; + c.ConfigObject = new ConfigObject + { + HideHostname = true, + HideDownloadButton = true + }; + }); + return app; + } } diff --git a/AutoHub.API/Program.cs b/AutoHub.API/Program.cs index 25dd39f..e0f758d 100644 --- a/AutoHub.API/Program.cs +++ b/AutoHub.API/Program.cs @@ -50,6 +50,7 @@ app.UseDeveloperExceptionPage(); app.UseSwaggerDocumentation(); + app.UseRedocDocumentation(); } app.UseMiddleware(); @@ -59,4 +60,4 @@ app.UseAuthorization(); app.MapControllers(); -app.Run(); \ No newline at end of file +app.Run(); diff --git a/AutoHub.BusinessLogic/AutoHub.BusinessLogic.csproj b/AutoHub.BusinessLogic/AutoHub.BusinessLogic.csproj index c2725b0..7a87b7c 100644 --- a/AutoHub.BusinessLogic/AutoHub.BusinessLogic.csproj +++ b/AutoHub.BusinessLogic/AutoHub.BusinessLogic.csproj @@ -1,7 +1,8 @@  - net7.0 + net8.0 + latestmajor diff --git a/AutoHub.DataAccess/AutoHub.DataAccess.csproj b/AutoHub.DataAccess/AutoHub.DataAccess.csproj index 0c5590f..207af58 100644 --- a/AutoHub.DataAccess/AutoHub.DataAccess.csproj +++ b/AutoHub.DataAccess/AutoHub.DataAccess.csproj @@ -1,7 +1,8 @@  - net7.0 + net8.0 + latestmajor diff --git a/AutoHub.Domain/AutoHub.Domain.csproj b/AutoHub.Domain/AutoHub.Domain.csproj index 0a5b1e5..a7b8af1 100644 --- a/AutoHub.Domain/AutoHub.Domain.csproj +++ b/AutoHub.Domain/AutoHub.Domain.csproj @@ -1,9 +1,10 @@  - net7.0 + net8.0 enable enable + latestmajor diff --git a/AutoHub.Tests/AutoHub.Tests.csproj b/AutoHub.Tests/AutoHub.Tests.csproj index 0a77c6b..6e6c69b 100644 --- a/AutoHub.Tests/AutoHub.Tests.csproj +++ b/AutoHub.Tests/AutoHub.Tests.csproj @@ -1,9 +1,11 @@  - net7.0 + net8.0 false + + latestmajor diff --git a/global.json b/global.json index 36e1a9e..f6ba4b7 100644 --- a/global.json +++ b/global.json @@ -1,7 +1,7 @@ { "sdk": { - "version": "7.0.0", + "version": "8.0.0", "rollForward": "latestMajor", "allowPrerelease": false } -} \ No newline at end of file +} From 9c5ca8bb98a196662b44bc190881a931d2a6b770 Mon Sep 17 00:00:00 2001 From: nikitareshetnik Date: Thu, 10 Oct 2024 01:36:03 +0300 Subject: [PATCH 03/22] Added Dockerfile --- .dockerignore | 25 +++++++++++++++++++++++++ AutoHub.API/AutoHub.API.csproj | 1 + AutoHub.sln | 2 ++ Dockerfile | 26 ++++++++++++++++++++++++++ 4 files changed, 54 insertions(+) create mode 100644 .dockerignore create mode 100644 Dockerfile diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..38bece4 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,25 @@ +**/.dockerignore +**/.env +**/.git +**/.gitignore +**/.project +**/.settings +**/.toolstarget +**/.vs +**/.vscode +**/.idea +**/*.*proj.user +**/*.dbmdl +**/*.jfm +**/azds.yaml +**/bin +**/charts +**/docker-compose* +**/Dockerfile* +**/node_modules +**/npm-debug.log +**/obj +**/secrets.dev.yaml +**/values.dev.yaml +LICENSE +README.md \ No newline at end of file diff --git a/AutoHub.API/AutoHub.API.csproj b/AutoHub.API/AutoHub.API.csproj index 1d61242..a02193a 100644 --- a/AutoHub.API/AutoHub.API.csproj +++ b/AutoHub.API/AutoHub.API.csproj @@ -5,6 +5,7 @@ net8.0 d05e2abf-9390-4c8d-8b73-ec1fade60694 latestmajor + Linux diff --git a/AutoHub.sln b/AutoHub.sln index 72ff642..ea62aa9 100644 --- a/AutoHub.sln +++ b/AutoHub.sln @@ -12,6 +12,8 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{253F40F1-053B-4212-B27E-54182928D15E}" ProjectSection(SolutionItems) = preProject .editorconfig = .editorconfig + Dockerfile = Dockerfile + .dockerignore = .dockerignore EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AutoHub.BusinessLogic", "AutoHub.BusinessLogic\AutoHub.BusinessLogic.csproj", "{BDCDD86A-CA38-4D40-A727-7003001F3F22}" diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..e9cd286 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,26 @@ +FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base +USER $APP_UID +WORKDIR /app +EXPOSE 8080 +EXPOSE 8081 + +FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build +ARG BUILD_CONFIGURATION=Release +WORKDIR /src +COPY ["AutoHub.API/AutoHub.API.csproj", "AutoHub.API/"] +COPY ["AutoHub.BusinessLogic/AutoHub.BusinessLogic.csproj", "AutoHub.BusinessLogic/"] +COPY ["AutoHub.DataAccess/AutoHub.DataAccess.csproj", "AutoHub.DataAccess/"] +COPY ["AutoHub.Domain/AutoHub.Domain.csproj", "AutoHub.Domain/"] +RUN dotnet restore "AutoHub.API/AutoHub.API.csproj" +COPY . . +WORKDIR "/src/AutoHub.API" +RUN dotnet build "AutoHub.API.csproj" -c $BUILD_CONFIGURATION -o /app/build + +FROM build AS publish +ARG BUILD_CONFIGURATION=Release +RUN dotnet publish "AutoHub.API.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "AutoHub.API.dll"] From 8e412a192f1fb07d376c9b8e6686f6d36f45f89a Mon Sep 17 00:00:00 2001 From: nikitareshetnik Date: Thu, 10 Oct 2024 03:09:27 +0300 Subject: [PATCH 04/22] Multiple improvements and refactoring. Using Az DB --- AutoHub.API/AutoHub.API.csproj | 33 +++---- .../Controllers/AuthenticationController.cs | 17 +--- AutoHub.API/Controllers/CarBrandController.cs | 15 +-- AutoHub.API/Controllers/CarColorController.cs | 15 +-- AutoHub.API/Controllers/CarController.cs | 17 +--- AutoHub.API/Controllers/CarModelController.cs | 15 +-- AutoHub.API/Controllers/LotBidController.cs | 13 +-- AutoHub.API/Controllers/LotController.cs | 15 +-- AutoHub.API/Controllers/UserBidController.cs | 9 +- AutoHub.API/Controllers/UserController.cs | 13 +-- .../ApplicationExceptionMiddleware.cs | 11 +-- AutoHub.API/Program.cs | 9 +- AutoHub.API/Validators/PaginationValidator.cs | 2 +- AutoHub.API/appsettings.Development.json | 9 +- AutoHub.API/appsettings.json | 8 +- .../AutoHub.BusinessLogic.csproj | 16 +-- .../Jobs/LotWinnerDeterminantJob.cs | 12 +-- .../Services/AuthenticationService.cs | 19 ++-- AutoHub.BusinessLogic/Services/BidService.cs | 50 ++++------ .../Services/CarBrandService.cs | 39 +++----- .../Services/CarColorService.cs | 39 +++----- .../Services/CarModelService.cs | 39 +++----- AutoHub.BusinessLogic/Services/CarService.cs | 55 +++++------ .../Services/EmailService.cs | 9 +- AutoHub.BusinessLogic/Services/LotService.cs | 60 +++++------- AutoHub.BusinessLogic/Services/UserService.cs | 98 +++++++++---------- AutoHub.DataAccess/AutoHub.DataAccess.csproj | 19 ++-- AutoHub.DataAccess/AutoHubContext.cs | 2 +- AutoHub.Domain/AutoHub.Domain.csproj | 8 +- .../Entities/Identity/ApplicationUser.cs | 15 +-- AutoHub.Tests/AutoHub.Tests.csproj | 18 ++-- 31 files changed, 273 insertions(+), 426 deletions(-) diff --git a/AutoHub.API/AutoHub.API.csproj b/AutoHub.API/AutoHub.API.csproj index a02193a..6cbedde 100644 --- a/AutoHub.API/AutoHub.API.csproj +++ b/AutoHub.API/AutoHub.API.csproj @@ -21,32 +21,31 @@ - - - + + - - - + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + - - - - - + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + - - - - + + + + diff --git a/AutoHub.API/Controllers/AuthenticationController.cs b/AutoHub.API/Controllers/AuthenticationController.cs index 2f5c5bc..93c049d 100644 --- a/AutoHub.API/Controllers/AuthenticationController.cs +++ b/AutoHub.API/Controllers/AuthenticationController.cs @@ -15,16 +15,9 @@ namespace AutoHub.API.Controllers; [AllowAnonymous] [Route("api/[controller]")] [Produces("application/json")] -public class AuthenticationController : Controller +public class AuthenticationController(IUserService userService, IMapper mapper) : ControllerBase { - private readonly IMapper _mapper; - private readonly IUserService _userService; - - public AuthenticationController(IUserService userService, IMapper mapper) - { - _userService = userService ?? throw new ArgumentNullException(nameof(userService)); - _mapper = mapper; - } + private readonly IUserService _userService = userService ?? throw new ArgumentNullException(nameof(userService)); /// /// Log-in with credentials. @@ -43,9 +36,9 @@ public async Task LoginUser([FromBody] UserLoginRequest model) { await _userService.Logout(); - var mappedUser = _mapper.Map(model); + var mappedUser = mapper.Map(model); var authModel = await _userService.Login(mappedUser); - var mappedAuthModel = _mapper.Map(authModel); + var mappedAuthModel = mapper.Map(authModel); return Ok(mappedAuthModel); } @@ -63,7 +56,7 @@ public async Task LoginUser([FromBody] UserLoginRequest model) [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task RegisterUser([FromBody] UserRegisterRequest model) { - var mappedUser = _mapper.Map(model); + var mappedUser = mapper.Map(model); await _userService.Register(mappedUser); return StatusCode((int)HttpStatusCode.Created); diff --git a/AutoHub.API/Controllers/CarBrandController.cs b/AutoHub.API/Controllers/CarBrandController.cs index 01a3b13..593942e 100644 --- a/AutoHub.API/Controllers/CarBrandController.cs +++ b/AutoHub.API/Controllers/CarBrandController.cs @@ -19,16 +19,9 @@ namespace AutoHub.API.Controllers; [Authorize] [Route("api/[controller]s")] [Produces("application/json")] -public class CarBrandController : Controller +public class CarBrandController(ICarBrandService carBrandService, IMapper mapper) : ControllerBase { - private readonly ICarBrandService _carBrandService; - private readonly IMapper _mapper; - - public CarBrandController(ICarBrandService carBrandService, IMapper mapper) - { - _carBrandService = carBrandService ?? throw new ArgumentNullException(nameof(carBrandService)); - _mapper = mapper; - } + private readonly ICarBrandService _carBrandService = carBrandService ?? throw new ArgumentNullException(nameof(carBrandService)); /// /// Get all car brands. @@ -68,7 +61,7 @@ public async Task GetAllCarBrands([FromQuery] PaginationParameter [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task CreateCarBrand([FromBody] CarBrandCreateRequest model) { - var mappedCarBrand = _mapper.Map(model); + var mappedCarBrand = mapper.Map(model); await _carBrandService.Create(mappedCarBrand); return StatusCode((int)HttpStatusCode.Created); @@ -95,7 +88,7 @@ public async Task CreateCarBrand([FromBody] CarBrandCreateRequest [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task UpdateCarBrand(int carBrandId, [FromBody] CarBrandUpdateRequest model) { - var mappedCarBrand = _mapper.Map(model); + var mappedCarBrand = mapper.Map(model); await _carBrandService.Update(carBrandId, mappedCarBrand); return NoContent(); diff --git a/AutoHub.API/Controllers/CarColorController.cs b/AutoHub.API/Controllers/CarColorController.cs index 3143c5e..8a50f71 100644 --- a/AutoHub.API/Controllers/CarColorController.cs +++ b/AutoHub.API/Controllers/CarColorController.cs @@ -19,16 +19,9 @@ namespace AutoHub.API.Controllers; [Authorize] [Route("api/[controller]s")] [Produces("application/json")] -public class CarColorController : Controller +public class CarColorController(ICarColorService carColorService, IMapper mapper) : ControllerBase { - private readonly ICarColorService _carColorService; - private readonly IMapper _mapper; - - public CarColorController(ICarColorService carColorService, IMapper mapper) - { - _carColorService = carColorService ?? throw new ArgumentNullException(nameof(carColorService)); - _mapper = mapper; - } + private readonly ICarColorService _carColorService = carColorService ?? throw new ArgumentNullException(nameof(carColorService)); /// /// Get all car colors. @@ -69,7 +62,7 @@ public async Task GetAllCarColors([FromQuery] PaginationParameter [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task CreateCarColor([FromBody] CarColorCreateRequest model) { - var mappedCarColor = _mapper.Map(model); + var mappedCarColor = mapper.Map(model); await _carColorService.Create(mappedCarColor); return StatusCode((int)HttpStatusCode.Created); @@ -96,7 +89,7 @@ public async Task CreateCarColor([FromBody] CarColorCreateRequest [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task UpdateCarColor(int carColorId, [FromBody] CarColorUpdateRequest model) { - var mappedCarColor = _mapper.Map(model); + var mappedCarColor = mapper.Map(model); await _carColorService.Update(carColorId, mappedCarColor); return NoContent(); diff --git a/AutoHub.API/Controllers/CarController.cs b/AutoHub.API/Controllers/CarController.cs index 94a48ef..620606c 100644 --- a/AutoHub.API/Controllers/CarController.cs +++ b/AutoHub.API/Controllers/CarController.cs @@ -20,16 +20,9 @@ namespace AutoHub.API.Controllers; [Authorize] [Route("api/[controller]s")] [Produces("application/json")] -public class CarController : Controller +public class CarController(ICarService carService, IMapper mapper) : ControllerBase { - private readonly ICarService _carService; - private readonly IMapper _mapper; - - public CarController(ICarService carService, IMapper mapper) - { - _carService = carService ?? throw new ArgumentNullException(nameof(carService)); - _mapper = mapper; - } + private readonly ICarService _carService = carService ?? throw new ArgumentNullException(nameof(carService)); /// /// Get all cars. @@ -67,7 +60,7 @@ public async Task GetAllCars([FromQuery] PaginationParameters pag public async Task GetCarById(int carId) { var car = await _carService.GetById(carId); - var mappedCar = _mapper.Map(car); + var mappedCar = mapper.Map(car); return Ok(mappedCar); } @@ -90,7 +83,7 @@ public async Task GetCarById(int carId) [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task CreateCar([FromBody] CarCreateRequest model) { - var mappedCar = _mapper.Map(model); + var mappedCar = mapper.Map(model); await _carService.Create(mappedCar); return StatusCode((int)HttpStatusCode.Created); @@ -118,7 +111,7 @@ public async Task CreateCar([FromBody] CarCreateRequest model) [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task UpdateCar(int carId, [FromBody] CarUpdateRequest model) { - var mappedCar = _mapper.Map(model); + var mappedCar = mapper.Map(model); await _carService.Update(carId, mappedCar); return NoContent(); diff --git a/AutoHub.API/Controllers/CarModelController.cs b/AutoHub.API/Controllers/CarModelController.cs index c326b95..10b7ffe 100644 --- a/AutoHub.API/Controllers/CarModelController.cs +++ b/AutoHub.API/Controllers/CarModelController.cs @@ -19,16 +19,9 @@ namespace AutoHub.API.Controllers; [Authorize] [Route("api/[controller]s")] [Produces("application/json")] -public class CarModelController : Controller +public class CarModelController(ICarModelService carModelService, IMapper mapper) : ControllerBase { - private readonly ICarModelService _carModelService; - private readonly IMapper _mapper; - - public CarModelController(ICarModelService carModelService, IMapper mapper) - { - _carModelService = carModelService ?? throw new ArgumentNullException(nameof(carModelService)); - _mapper = mapper; - } + private readonly ICarModelService _carModelService = carModelService ?? throw new ArgumentNullException(nameof(carModelService)); /// /// Get all car models. @@ -68,7 +61,7 @@ public async Task GetAllCarModels([FromQuery] PaginationParameter [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task CreateCarModel([FromBody] CarModelCreateRequest model) { - var mappedCarModel = _mapper.Map(model); + var mappedCarModel = mapper.Map(model); await _carModelService.Create(mappedCarModel); return StatusCode((int)HttpStatusCode.Created); @@ -94,7 +87,7 @@ public async Task CreateCarModel([FromBody] CarModelCreateRequest [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task UpdateCarModel(int carModelId, [FromBody] CarModelUpdateRequest model) { - var mappedCarModel = _mapper.Map(model); + var mappedCarModel = mapper.Map(model); await _carModelService.Update(carModelId, mappedCarModel); return NoContent(); diff --git a/AutoHub.API/Controllers/LotBidController.cs b/AutoHub.API/Controllers/LotBidController.cs index b97dd09..32ea9c2 100644 --- a/AutoHub.API/Controllers/LotBidController.cs +++ b/AutoHub.API/Controllers/LotBidController.cs @@ -19,16 +19,9 @@ namespace AutoHub.API.Controllers; [Authorize] [Route("api/Lots/{lotId}/Bids")] [Produces("application/json")] -public class LotBidController : Controller +public class LotBidController(IBidService bidService, IMapper mapper) : ControllerBase { - private readonly IBidService _bidService; - private readonly IMapper _mapper; - - public LotBidController(IBidService bidService, IMapper mapper) - { - _bidService = bidService ?? throw new ArgumentNullException(nameof(bidService)); - _mapper = mapper; - } + private readonly IBidService _bidService = bidService ?? throw new ArgumentNullException(nameof(bidService)); /// /// Get all bids of specific lot. @@ -74,7 +67,7 @@ public async Task GetLotBids(int lotId, [FromQuery] PaginationPar [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task CreateBid(int lotId, [FromBody] BidCreateRequest model) { - var mappedBid = _mapper.Map(model); + var mappedBid = mapper.Map(model); await _bidService.Create(lotId, mappedBid); return StatusCode((int)HttpStatusCode.Created); diff --git a/AutoHub.API/Controllers/LotController.cs b/AutoHub.API/Controllers/LotController.cs index e23ad93..7072113 100644 --- a/AutoHub.API/Controllers/LotController.cs +++ b/AutoHub.API/Controllers/LotController.cs @@ -19,16 +19,9 @@ namespace AutoHub.API.Controllers; [Authorize] [Route("api/[controller]s")] [Produces("application/json")] -public class LotController : Controller +public class LotController(ILotService lotService, IMapper mapper) : ControllerBase { - private readonly ILotService _lotService; - private readonly IMapper _mapper; - - public LotController(ILotService lotService, IMapper mapper) - { - _lotService = lotService ?? throw new ArgumentNullException(nameof(lotService)); - _mapper = mapper; - } + private readonly ILotService _lotService = lotService ?? throw new ArgumentNullException(nameof(lotService)); /// /// Get all lots. @@ -108,7 +101,7 @@ public async Task GetLotById(int lotId) [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task CreateLot([FromBody] LotCreateRequest model) { - var mappedLot = _mapper.Map(model); + var mappedLot = mapper.Map(model); await _lotService.Create(mappedLot); return StatusCode((int)HttpStatusCode.Created); @@ -136,7 +129,7 @@ public async Task CreateLot([FromBody] LotCreateRequest model) [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task UpdateLot(int lotId, [FromBody] LotUpdateRequest model) { - var mappedLot = _mapper.Map(model); + var mappedLot = mapper.Map(model); await _lotService.Update(lotId, mappedLot); return NoContent(); diff --git a/AutoHub.API/Controllers/UserBidController.cs b/AutoHub.API/Controllers/UserBidController.cs index 8b34cc0..132ec86 100644 --- a/AutoHub.API/Controllers/UserBidController.cs +++ b/AutoHub.API/Controllers/UserBidController.cs @@ -16,14 +16,9 @@ namespace AutoHub.API.Controllers; [Authorize(Roles = AuthorizationRoles.Administrator)] [Route("api/Users/{userId}/Bids")] [Produces("application/json")] -public class UserBidController : Controller +public class UserBidController(IBidService bidService) : ControllerBase { - private readonly IBidService _bidService; - - public UserBidController(IBidService bidService) - { - _bidService = bidService ?? throw new ArgumentNullException(nameof(bidService)); - } + private readonly IBidService _bidService = bidService ?? throw new ArgumentNullException(nameof(bidService)); /// /// Returns all bids created by user. diff --git a/AutoHub.API/Controllers/UserController.cs b/AutoHub.API/Controllers/UserController.cs index 20a9ac0..780d343 100644 --- a/AutoHub.API/Controllers/UserController.cs +++ b/AutoHub.API/Controllers/UserController.cs @@ -18,16 +18,9 @@ namespace AutoHub.API.Controllers; [Authorize(Roles = AuthorizationRoles.Administrator)] [Route("api/[controller]s")] [Produces("application/json")] -public class UserController : Controller +public class UserController(IUserService userService, IMapper mapper) : ControllerBase { - private readonly IMapper _mapper; - private readonly IUserService _userService; - - public UserController(IUserService userService, IMapper mapper) - { - _userService = userService ?? throw new ArgumentNullException(nameof(userService)); - _mapper = mapper; - } + private readonly IUserService _userService = userService ?? throw new ArgumentNullException(nameof(userService)); /// /// Gets all users. @@ -95,7 +88,7 @@ public async Task GetUserById(int userId) [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task UpdateUser(int userId, [FromBody] UserUpdateRequest model) { - var mappedUser = _mapper.Map(model); + var mappedUser = mapper.Map(model); await _userService.Update(userId, mappedUser); return NoContent(); diff --git a/AutoHub.API/Middlewares/ApplicationExceptionMiddleware.cs b/AutoHub.API/Middlewares/ApplicationExceptionMiddleware.cs index 5ee3d6a..4c1cdea 100644 --- a/AutoHub.API/Middlewares/ApplicationExceptionMiddleware.cs +++ b/AutoHub.API/Middlewares/ApplicationExceptionMiddleware.cs @@ -7,20 +7,13 @@ namespace AutoHub.API.Middlewares; -public class ApplicationExceptionMiddleware +public class ApplicationExceptionMiddleware(RequestDelegate next) { - private readonly RequestDelegate _next; - - public ApplicationExceptionMiddleware(RequestDelegate next) - { - _next = next; - } - public async Task InvokeAsync(HttpContext httpContext) { try { - await _next(httpContext); + await next(httpContext); } catch (NotFoundException nfEx) { diff --git a/AutoHub.API/Program.cs b/AutoHub.API/Program.cs index e0f758d..aae3671 100644 --- a/AutoHub.API/Program.cs +++ b/AutoHub.API/Program.cs @@ -15,7 +15,7 @@ var builder = WebApplication.CreateBuilder(args); -builder.Services.AddDbContext(opt => opt.UseNpgsql(builder.Configuration.GetConnectionString("PostgresConnectionString"))); +builder.Services.AddDbContext(opt => opt.UseSqlServer(builder.Configuration.GetConnectionString("AzureSqlServerConnectionString"))); builder.Configuration.AddEnvironmentVariables().AddUserSecrets(); builder.Services.AddControllers(); builder.Services.AddServices(); @@ -49,10 +49,10 @@ } app.UseDeveloperExceptionPage(); - app.UseSwaggerDocumentation(); - app.UseRedocDocumentation(); } +app.UseSwaggerDocumentation(); +app.UseRedocDocumentation(); app.UseMiddleware(); app.UseHttpsRedirection(); app.UseRouting(); @@ -60,4 +60,5 @@ app.UseAuthorization(); app.MapControllers(); -app.Run(); +await app.RunAsync(); + diff --git a/AutoHub.API/Validators/PaginationValidator.cs b/AutoHub.API/Validators/PaginationValidator.cs index 34bcd91..48a6534 100644 --- a/AutoHub.API/Validators/PaginationValidator.cs +++ b/AutoHub.API/Validators/PaginationValidator.cs @@ -11,7 +11,7 @@ public class PaginationValidator : AbstractValidator public PaginationValidator() { RuleFor(p => p) - .Must(p => p.After.IsNullOrEmpty() || p.Before.IsNullOrEmpty()) + .Must(p => string.IsNullOrEmpty(p.After) || string.IsNullOrEmpty(p.Before)) .WithMessage(p => $"Only '{nameof(p.After)}' OR '{nameof(p.Before)}' can be provided, but not both.") .WithName(nameof(PaginationParameters)); diff --git a/AutoHub.API/appsettings.Development.json b/AutoHub.API/appsettings.Development.json index 904c4c1..eb943d8 100644 --- a/AutoHub.API/appsettings.Development.json +++ b/AutoHub.API/appsettings.Development.json @@ -7,12 +7,13 @@ } }, "JwtConfiguration":{ - "Key": "AutoHubTestingKey", - "Issuer": "AutoHubIssuer", - "Audience": "AutoHubAudience", + "Key": "AutoHubTestingKey-1c60efe4-7064-434e-af4a-2de961bf1e49-51f24c90-df26-4f3f-a27f-bd92b4914055", + "Issuer": "AutoHubIssuer-c002f16a-9f95-4db7-830e-b8f3e827d6f9-15a03a47-3eda-4ab5-8579-37a8d0e717af", + "Audience": "AutoHubAudience-c42cfd12-4e98-45f7-89aa-f31e33d51eb1-a72ac979-cf72-4c43-b0fe-80b0ed1e4307", "HoursToExpire": 3 }, "ConnectionStrings": { - "PostgresConnectionString": "Host=localhost;Port=5432;Database=AutoHubDb;Username=postgres;Password=admin;Include Error Detail=true;" + "PostgresConnectionString": "Host=localhost;Port=5432;Database=AutoHubDb;Username=postgres;Password=admin;Include Error Detail=true;", + "AzureSqlServerConnectionString": "Server=autohub-db.database.windows.net,1433;Initial Catalog=AutoHubDb;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;Authentication=Active Directory Default" } } \ No newline at end of file diff --git a/AutoHub.API/appsettings.json b/AutoHub.API/appsettings.json index a48c3c1..de13105 100644 --- a/AutoHub.API/appsettings.json +++ b/AutoHub.API/appsettings.json @@ -8,12 +8,12 @@ }, "AllowedHosts": "*", "JwtConfiguration":{ - "Key": "AutoHubTestingKey", - "Issuer": "AutoHubIssuer", - "Audience": "AutoHubAudience", + "Key": "AutoHubTestingKey-1c60efe4-7064-434e-af4a-2de961bf1e49-51f24c90-df26-4f3f-a27f-bd92b4914055", + "Issuer": "AutoHubIssuer-c002f16a-9f95-4db7-830e-b8f3e827d6f9-15a03a47-3eda-4ab5-8579-37a8d0e717af", + "Audience": "AutoHubAudience-c42cfd12-4e98-45f7-89aa-f31e33d51eb1-a72ac979-cf72-4c43-b0fe-80b0ed1e4307", "HoursToExpire": 3 }, "ConnectionStrings": { - "PostgresConnectionString": "Host=localhost;Port=5432;Database=AutoHubDb;Username=postgres;Password=admin;Include Error Detail=true;" + "AzureSqlServerConnectionString": "Server=autohub-db.database.windows.net,1433;Initial Catalog=AutoHubDb;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;Authentication=Active Directory Default" } } \ No newline at end of file diff --git a/AutoHub.BusinessLogic/AutoHub.BusinessLogic.csproj b/AutoHub.BusinessLogic/AutoHub.BusinessLogic.csproj index 7a87b7c..cb10645 100644 --- a/AutoHub.BusinessLogic/AutoHub.BusinessLogic.csproj +++ b/AutoHub.BusinessLogic/AutoHub.BusinessLogic.csproj @@ -11,18 +11,18 @@ - + - - - - - - + + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/AutoHub.BusinessLogic/Jobs/LotWinnerDeterminantJob.cs b/AutoHub.BusinessLogic/Jobs/LotWinnerDeterminantJob.cs index cbbfd09..dd77889 100644 --- a/AutoHub.BusinessLogic/Jobs/LotWinnerDeterminantJob.cs +++ b/AutoHub.BusinessLogic/Jobs/LotWinnerDeterminantJob.cs @@ -9,16 +9,10 @@ namespace AutoHub.BusinessLogic.Jobs; -public class LotWinnerDeterminantJob : IJob +public class LotWinnerDeterminantJob(ILotService lotService, IBidService bidService) : IJob { - private readonly ILotService _lotService; - private readonly IBidService _bidService; - - public LotWinnerDeterminantJob(ILotService lotService, IBidService bidService) - { - _lotService = lotService ?? throw new ArgumentNullException(nameof(lotService)); - _bidService = bidService ?? throw new ArgumentNullException(nameof(bidService)); - } + private readonly ILotService _lotService = lotService ?? throw new ArgumentNullException(nameof(lotService)); + private readonly IBidService _bidService = bidService ?? throw new ArgumentNullException(nameof(bidService)); public async Task Execute(IJobExecutionContext context) { diff --git a/AutoHub.BusinessLogic/Services/AuthenticationService.cs b/AutoHub.BusinessLogic/Services/AuthenticationService.cs index 8c0510d..7c8a2e9 100644 --- a/AutoHub.BusinessLogic/Services/AuthenticationService.cs +++ b/AutoHub.BusinessLogic/Services/AuthenticationService.cs @@ -15,16 +15,11 @@ namespace AutoHub.BusinessLogic.Services; -public class AuthenticationService : IAuthenticationService +public class AuthenticationService(IOptions jwtOptions, RoleManager roleManager) + : IAuthenticationService { - private readonly JwtConfiguration _jwtOptions; - private readonly IList _roles; - - public AuthenticationService(IOptions jwtOptions, RoleManager roleManager) - { - _jwtOptions = jwtOptions.Value; - _roles = roleManager.Roles.ToList(); - } + private readonly JwtConfiguration _jwtOptions = jwtOptions.Value; + private readonly IList _roles = roleManager.Roles.ToList(); public Task GenerateWebTokenForUser(ApplicationUser user) { @@ -32,11 +27,11 @@ public Task GenerateWebTokenForUser(ApplicationUser user) var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtOptions.Key)); var claims = new List { - new Claim(JwtRegisteredClaimNames.NameId, user.UserName), - new Claim(JwtRegisteredClaimNames.Email, user.Email) + new Claim(JwtRegisteredClaimNames.NameId, user.UserName ?? throw new ArgumentNullException(user.UserName)), + new Claim(JwtRegisteredClaimNames.Email, user.Email ?? throw new ArgumentNullException(user.Email)) }; - claims.AddRange(_roles.Select(r => new Claim(ClaimTypes.Role, r.Name))); + claims.AddRange(_roles.Select(role => new Claim(ClaimTypes.Role, role.Name ?? throw new ArgumentNullException(user.Email)))); var tokenDescriptor = new SecurityTokenDescriptor { diff --git a/AutoHub.BusinessLogic/Services/BidService.cs b/AutoHub.BusinessLogic/Services/BidService.cs index 8b92a58..7eae2ee 100644 --- a/AutoHub.BusinessLogic/Services/BidService.cs +++ b/AutoHub.BusinessLogic/Services/BidService.cs @@ -17,29 +17,19 @@ namespace AutoHub.BusinessLogic.Services; -public class BidService : IBidService +public class BidService(AutoHubContext context, IMapper mapper, UserManager userManager) + : IBidService { - private readonly AutoHubContext _context; - private readonly IMapper _mapper; - private readonly UserManager _userManager; - - public BidService(AutoHubContext context, IMapper mapper, UserManager userManager) - { - _context = context; - _mapper = mapper; - _userManager = userManager; - } - public async Task> GetUserBids(int userId, PaginationParameters paginationParameters) { - if (await _userManager.FindByIdAsync(userId.ToString()) is null) + if (await userManager.FindByIdAsync(userId.ToString()) is null) { throw new NotFoundException($"User with ID {userId} not exist."); } List bids; var limit = paginationParameters.Limit ?? DefaultPaginationValues.DefaultLimit; - var query = _context.Bids + var query = context.Bids .OrderBy(x => x.BidId) .Where(bid => bid.UserId == userId) .AsQueryable(); @@ -52,20 +42,20 @@ public async Task> GetUserBids(int userId, Paginatio else if (paginationParameters.After is null && paginationParameters.Before is not null) { var before = Convert.ToInt32(Base64Helper.Decode(paginationParameters.Before)); - bids = await _context.Bids.Where(bid => bid.BidId < before).Take(limit).ToListAsync(); + bids = await context.Bids.Where(bid => bid.BidId < before).Take(limit).ToListAsync(); } else { - bids = await _context.Bids.Take(limit).ToListAsync(); + bids = await context.Bids.Take(limit).ToListAsync(); } - var mappedBids = _mapper.Map>(bids); + var mappedBids = mapper.Map>(bids); return mappedBids; } public async Task> GetLotBids(int lotId, PaginationParameters paginationParameters) { - if (await _context.Lots.FindAsync(lotId) is null) + if (await context.Lots.FindAsync(lotId) is null) { throw new NotFoundException($"Lot with ID {lotId} not exist."); } @@ -74,7 +64,7 @@ public async Task> GetLotBids(int lotId, PaginationP var limit = paginationParameters.Limit ?? DefaultPaginationValues.DefaultLimit; var after = Convert.ToInt32(Base64Helper.Decode(paginationParameters.After)); var before = Convert.ToInt32(Base64Helper.Decode(paginationParameters.Before)); - var query = _context.Bids + var query = context.Bids .OrderBy(x => x.BidId) .Where(bid => bid.LotId == lotId) .AsQueryable(); @@ -85,34 +75,34 @@ public async Task> GetLotBids(int lotId, PaginationP } else if (paginationParameters.After is null && paginationParameters.Before is not null) { - bids = await _context.Bids.Where(bid => bid.BidId < before).Take(limit).ToListAsync(); + bids = await context.Bids.Where(bid => bid.BidId < before).Take(limit).ToListAsync(); } else { - bids = await _context.Bids.Take(limit).ToListAsync(); + bids = await context.Bids.Take(limit).ToListAsync(); } - var mappedBids = _mapper.Map>(bids); + var mappedBids = mapper.Map>(bids); return mappedBids; } public async Task Create(int lotId, BidCreateRequestDTO createBidDTO) { - if (await _context.Lots.FindAsync(lotId) is null) + if (await context.Lots.FindAsync(lotId) is null) { throw new NotFoundException($"Lot with ID {lotId} not exist."); } - if (await _userManager.FindByIdAsync(createBidDTO.UserId.ToString()) is null) + if (await userManager.FindByIdAsync(createBidDTO.UserId.ToString()) is null) { throw new NotFoundException($"User with ID {createBidDTO.UserId} not exist."); } - var lotBids = _context.Bids.Where(x => x.LotId == lotId); + var lotBids = context.Bids.Where(x => x.LotId == lotId); - if (lotBids.Any()) + if (await lotBids.AnyAsync()) { - var biggestLotBid = lotBids.Max(x => x.BidValue); + var biggestLotBid = await lotBids.MaxAsync(x => x.BidValue); if (createBidDTO.BidValue < biggestLotBid) { @@ -120,11 +110,11 @@ public async Task Create(int lotId, BidCreateRequestDTO createBidDTO) } } - var bid = _mapper.Map(createBidDTO); + var bid = mapper.Map(createBidDTO); bid.LotId = lotId; bid.BidTime = DateTime.UtcNow; - await _context.Bids.AddAsync(bid); - await _context.SaveChangesAsync(); + await context.Bids.AddAsync(bid); + await context.SaveChangesAsync(); } } diff --git a/AutoHub.BusinessLogic/Services/CarBrandService.cs b/AutoHub.BusinessLogic/Services/CarBrandService.cs index 32e7b29..f8cac8b 100644 --- a/AutoHub.BusinessLogic/Services/CarBrandService.cs +++ b/AutoHub.BusinessLogic/Services/CarBrandService.cs @@ -15,22 +15,13 @@ namespace AutoHub.BusinessLogic.Services; -public class CarBrandService : ICarBrandService +public class CarBrandService(AutoHubContext context, IMapper mapper) : ICarBrandService { - private readonly AutoHubContext _context; - private readonly IMapper _mapper; - - public CarBrandService(AutoHubContext context, IMapper mapper) - { - _context = context; - _mapper = mapper; - } - public async Task> GetAll(PaginationParameters paginationParameters) { List carBrands; var limit = paginationParameters.Limit ?? DefaultPaginationValues.DefaultLimit; - var query = _context.CarBrands + var query = context.CarBrands .OrderBy(x => x.CarBrandId) .Take(limit) .AsQueryable(); @@ -50,47 +41,47 @@ public async Task> GetAll(PaginationParameters carBrands = await query.ToListAsync(); } - var mappedCarBrands = _mapper.Map>(carBrands); + var mappedCarBrands = mapper.Map>(carBrands); return mappedCarBrands; } public async Task GetById(int carBrandId) { - var brand = await _context.CarBrands.FindAsync(carBrandId) ?? throw new NotFoundException($"Car brand with ID {carBrandId} not exist."); + var brand = await context.CarBrands.FindAsync(carBrandId) ?? throw new NotFoundException($"Car brand with ID {carBrandId} not exist."); - var mappedBrand = _mapper.Map(brand); + var mappedBrand = mapper.Map(brand); return mappedBrand; } public async Task Create(CarBrandCreateRequestDTO createBrandDTO) { - var isDuplicate = await _context.CarBrands.AnyAsync(carBrand => carBrand.CarBrandName == createBrandDTO.CarBrandName); + var isDuplicate = await context.CarBrands.AnyAsync(carBrand => carBrand.CarBrandName == createBrandDTO.CarBrandName); if (isDuplicate) { throw new DuplicateException($"\"{createBrandDTO.CarBrandName}\" already exists."); } - var brand = _mapper.Map(createBrandDTO); - await _context.CarBrands.AddAsync(brand); - await _context.SaveChangesAsync(); + var brand = mapper.Map(createBrandDTO); + await context.CarBrands.AddAsync(brand); + await context.SaveChangesAsync(); } public async Task Update(int carBrandId, CarBrandUpdateRequestDTO updateBrandDTO) { - var carBrand = await _context.CarBrands.FindAsync(carBrandId) ?? throw new NotFoundException($"Car brand with ID {carBrandId} not exist."); + var carBrand = await context.CarBrands.FindAsync(carBrandId) ?? throw new NotFoundException($"Car brand with ID {carBrandId} not exist."); carBrand.CarBrandName = updateBrandDTO.CarBrandName; - _context.CarBrands.Update(carBrand); - await _context.SaveChangesAsync(); + context.CarBrands.Update(carBrand); + await context.SaveChangesAsync(); } public async Task Delete(int carBrandId) { - var carBrand = await _context.CarBrands.FindAsync(carBrandId) ?? throw new NotFoundException($"Car brand with ID {carBrandId} not exist."); + var carBrand = await context.CarBrands.FindAsync(carBrandId) ?? throw new NotFoundException($"Car brand with ID {carBrandId} not exist."); - _context.CarBrands.Remove(carBrand); - await _context.SaveChangesAsync(); + context.CarBrands.Remove(carBrand); + await context.SaveChangesAsync(); } } diff --git a/AutoHub.BusinessLogic/Services/CarColorService.cs b/AutoHub.BusinessLogic/Services/CarColorService.cs index 3aa7904..24a8b73 100644 --- a/AutoHub.BusinessLogic/Services/CarColorService.cs +++ b/AutoHub.BusinessLogic/Services/CarColorService.cs @@ -15,22 +15,13 @@ namespace AutoHub.BusinessLogic.Services; -public class CarColorService : ICarColorService +public class CarColorService(AutoHubContext context, IMapper mapper) : ICarColorService { - private readonly AutoHubContext _context; - private readonly IMapper _mapper; - - public CarColorService(AutoHubContext context, IMapper mapper) - { - _context = context; - _mapper = mapper; - } - public async Task> GetAll(PaginationParameters paginationParameters) { List carColors; var limit = paginationParameters.Limit ?? DefaultPaginationValues.DefaultLimit; - var query = _context.CarColors + var query = context.CarColors .OrderBy(x => x.CarColorId) .Take(limit) .AsQueryable(); @@ -50,47 +41,47 @@ public async Task> GetAll(PaginationParameters carColors = await query.ToListAsync(); } - var mappedCarColors = _mapper.Map>(carColors); + var mappedCarColors = mapper.Map>(carColors); return mappedCarColors; } public async Task GetById(int carColorId) { - var color = await _context.CarColors.FindAsync(carColorId) ?? throw new NotFoundException($"Car color with ID {carColorId} not exist."); + var color = await context.CarColors.FindAsync(carColorId) ?? throw new NotFoundException($"Car color with ID {carColorId} not exist."); - var mappedColor = _mapper.Map(color); + var mappedColor = mapper.Map(color); return mappedColor; } public async Task Create(CarColorCreateRequestDTO createColorDTO) { - var isDuplicate = await _context.CarColors.AnyAsync(carColor => carColor.CarColorName == createColorDTO.CarColorName); + var isDuplicate = await context.CarColors.AnyAsync(carColor => carColor.CarColorName == createColorDTO.CarColorName); if (isDuplicate.Equals(true)) { throw new DuplicateException($"\"{createColorDTO.CarColorName}\" already exists."); } - var color = _mapper.Map(createColorDTO); - await _context.CarColors.AddAsync(color); - await _context.SaveChangesAsync(); + var color = mapper.Map(createColorDTO); + await context.CarColors.AddAsync(color); + await context.SaveChangesAsync(); } public async Task Update(int carColorId, CarColorUpdateRequestDTO updateColorDTO) { - var carColor = await _context.CarColors.FindAsync(carColorId) ?? throw new NotFoundException($"Car color with ID {carColorId} not exist."); + var carColor = await context.CarColors.FindAsync(carColorId) ?? throw new NotFoundException($"Car color with ID {carColorId} not exist."); carColor.CarColorName = updateColorDTO.CarColorName; - _context.CarColors.Update(carColor); - await _context.SaveChangesAsync(); + context.CarColors.Update(carColor); + await context.SaveChangesAsync(); } public async Task Delete(int carColorId) { - var carColor = await _context.CarColors.FindAsync(carColorId) ?? throw new NotFoundException($"Car color with ID {carColorId} not exist."); + var carColor = await context.CarColors.FindAsync(carColorId) ?? throw new NotFoundException($"Car color with ID {carColorId} not exist."); - _context.CarColors.Remove(carColor); - await _context.SaveChangesAsync(); + context.CarColors.Remove(carColor); + await context.SaveChangesAsync(); } } diff --git a/AutoHub.BusinessLogic/Services/CarModelService.cs b/AutoHub.BusinessLogic/Services/CarModelService.cs index 9edff48..3cf7c61 100644 --- a/AutoHub.BusinessLogic/Services/CarModelService.cs +++ b/AutoHub.BusinessLogic/Services/CarModelService.cs @@ -15,22 +15,13 @@ namespace AutoHub.BusinessLogic.Services; -public class CarModelService : ICarModelService +public class CarModelService(AutoHubContext context, IMapper mapper) : ICarModelService { - private readonly AutoHubContext _context; - private readonly IMapper _mapper; - - public CarModelService(AutoHubContext context, IMapper mapper) - { - _context = context; - _mapper = mapper; - } - public async Task> GetAll(PaginationParameters paginationParameters) { List carModels; var limit = paginationParameters.Limit ?? DefaultPaginationValues.DefaultLimit; - var query = _context.CarModels + var query = context.CarModels .OrderBy(x => x.CarModelId) .Take(limit) .AsQueryable(); @@ -50,47 +41,47 @@ public async Task> GetAll(PaginationParameters carModels = await query.ToListAsync(); } - var mappedCarModel = _mapper.Map>(carModels); + var mappedCarModel = mapper.Map>(carModels); return mappedCarModel; } public async Task GetById(int carModelId) { - var model = await _context.CarModels.FindAsync(carModelId) ?? throw new NotFoundException($"Car model with ID {carModelId} not exist."); + var model = await context.CarModels.FindAsync(carModelId) ?? throw new NotFoundException($"Car model with ID {carModelId} not exist."); - var mappedModels = _mapper.Map(model); + var mappedModels = mapper.Map(model); return mappedModels; } public async Task Create(CarModelCreateRequestDTO createModelDTO) { - var isDuplicate = await _context.CarModels.AnyAsync(carModel => carModel.CarModelName == createModelDTO.CarModelName); + var isDuplicate = await context.CarModels.AnyAsync(carModel => carModel.CarModelName == createModelDTO.CarModelName); if (isDuplicate.Equals(true)) { throw new DuplicateException($"\"{createModelDTO.CarModelName}\" already exists."); } - var model = _mapper.Map(createModelDTO); - await _context.CarModels.AddAsync(model); - await _context.SaveChangesAsync(); + var model = mapper.Map(createModelDTO); + await context.CarModels.AddAsync(model); + await context.SaveChangesAsync(); } public async Task Update(int carModelId, CarModelUpdateRequestDTO updateModelDTO) { - var carModel = await _context.CarModels.FindAsync(carModelId) ?? throw new NotFoundException($"Car model with ID {carModelId} not exist."); + var carModel = await context.CarModels.FindAsync(carModelId) ?? throw new NotFoundException($"Car model with ID {carModelId} not exist."); carModel.CarModelName = updateModelDTO.CarModelName; - _context.CarModels.Update(carModel); - await _context.SaveChangesAsync(); + context.CarModels.Update(carModel); + await context.SaveChangesAsync(); } public async Task Delete(int carModelId) { - var carModel = await _context.CarModels.FindAsync(carModelId) ?? throw new NotFoundException($"Car model with ID {carModelId} not exist."); + var carModel = await context.CarModels.FindAsync(carModelId) ?? throw new NotFoundException($"Car model with ID {carModelId} not exist."); - _context.CarModels.Remove(carModel); - await _context.SaveChangesAsync(); + context.CarModels.Remove(carModel); + await context.SaveChangesAsync(); } } diff --git a/AutoHub.BusinessLogic/Services/CarService.cs b/AutoHub.BusinessLogic/Services/CarService.cs index 8e73a54..2dbcd57 100644 --- a/AutoHub.BusinessLogic/Services/CarService.cs +++ b/AutoHub.BusinessLogic/Services/CarService.cs @@ -16,22 +16,13 @@ namespace AutoHub.BusinessLogic.Services; -public class CarService : ICarService +public class CarService(AutoHubContext context, IMapper mapper) : ICarService { - private readonly AutoHubContext _context; - private readonly IMapper _mapper; - - public CarService(AutoHubContext context, IMapper mapper) - { - _context = context; - _mapper = mapper; - } - public async Task> GetAll(PaginationParameters paginationParameters) { List cars; var limit = paginationParameters.Limit ?? DefaultPaginationValues.DefaultLimit; - var query = _context.Cars + var query = context.Cars .OrderBy(x => x.CarId) .Take(limit) .AsQueryable(); @@ -51,33 +42,33 @@ public async Task> GetAll(PaginationParameters pagin cars = await query.ToListAsync(); } - var mappedCars = _mapper.Map>(cars); + var mappedCars = mapper.Map>(cars); return mappedCars; } public async Task GetById(int carId) { - var car = await _context.Cars.FindAsync(carId) ?? throw new NotFoundException($"Car with ID {carId} not exist."); + var car = await context.Cars.FindAsync(carId) ?? throw new NotFoundException($"Car with ID {carId} not exist."); - var mappedCar = _mapper.Map(car); + var mappedCar = mapper.Map(car); return mappedCar; } public async Task Create(CarCreateRequestDTO createCarDTO) { - var car = _mapper.Map(createCarDTO); + var car = mapper.Map(createCarDTO); - var brand = await _context.CarBrands.FirstOrDefaultAsync(carBrand => carBrand.CarBrandName == createCarDTO.CarBrand); - var model = await _context.CarModels.FirstOrDefaultAsync(carModel => carModel.CarModelName == createCarDTO.CarModel); - var color = await _context.CarColors.FirstOrDefaultAsync(carColor => carColor.CarColorName == createCarDTO.CarColor); + var brand = await context.CarBrands.FirstOrDefaultAsync(carBrand => carBrand.CarBrandName == createCarDTO.CarBrand); + var model = await context.CarModels.FirstOrDefaultAsync(carModel => carModel.CarModelName == createCarDTO.CarModel); + var color = await context.CarColors.FirstOrDefaultAsync(carColor => carColor.CarColorName == createCarDTO.CarColor); car.CarBrand = brand ?? new CarBrand { CarBrandName = createCarDTO.CarBrand }; car.CarModel = model ?? new CarModel { CarModelName = createCarDTO.CarModel }; car.CarColor = color ?? new CarColor { CarColorName = createCarDTO.CarColor }; car.CarStatusId = CarStatusEnum.New; - await _context.Cars.AddAsync(car); - await _context.SaveChangesAsync(); + await context.Cars.AddAsync(car); + await context.SaveChangesAsync(); } public async Task Update(int carId, CarUpdateRequestDTO updateCarDTO) @@ -87,23 +78,23 @@ public async Task Update(int carId, CarUpdateRequestDTO updateCarDTO) throw new EntityValidationException($"Incorrect {nameof(CarStatus.CarStatusId)} value."); } - var car = await _context.Cars.FindAsync(carId) ?? throw new NotFoundException($"Car with ID {carId} not exist."); + var car = await context.Cars.FindAsync(carId) ?? throw new NotFoundException($"Car with ID {carId} not exist."); if (car.CarBrand.CarBrandName != updateCarDTO.CarBrand) { - var brand = await _context.CarBrands.FirstOrDefaultAsync(carBrand => carBrand.CarBrandName == updateCarDTO.CarBrand); + var brand = await context.CarBrands.FirstOrDefaultAsync(carBrand => carBrand.CarBrandName == updateCarDTO.CarBrand); car.CarBrand = brand ?? new CarBrand { CarBrandName = updateCarDTO.CarBrand }; } if (car.CarModel.CarModelName != updateCarDTO.CarModel) { - var model = await _context.CarModels.FirstOrDefaultAsync(carModel => carModel.CarModelName == updateCarDTO.CarModel); + var model = await context.CarModels.FirstOrDefaultAsync(carModel => carModel.CarModelName == updateCarDTO.CarModel); car.CarModel = model ?? new CarModel { CarModelName = updateCarDTO.CarModel }; } if (car.CarColor.CarColorName != updateCarDTO.CarColor) { - var color = await _context.CarColors.FirstOrDefaultAsync(carColor => carColor.CarColorName == updateCarDTO.CarColor); + var color = await context.CarColors.FirstOrDefaultAsync(carColor => carColor.CarColorName == updateCarDTO.CarColor); car.CarColor = color ?? new CarColor { CarColorName = updateCarDTO.CarColor }; } @@ -116,8 +107,8 @@ public async Task Update(int carId, CarUpdateRequestDTO updateCarDTO) car.CostPrice = updateCarDTO.CostPrice; car.CarStatusId = (CarStatusEnum)updateCarDTO.CarStatusId; - _context.Cars.Update(car); - await _context.SaveChangesAsync(); + context.Cars.Update(car); + await context.SaveChangesAsync(); } public async Task UpdateStatus(int carId, int statusId) @@ -127,19 +118,19 @@ public async Task UpdateStatus(int carId, int statusId) throw new EntityValidationException($"Incorrect {nameof(CarStatus.CarStatusId)} value."); } - var car = await _context.Cars.FindAsync(carId) ?? throw new NotFoundException($"Car with ID {carId} not exist."); + var car = await context.Cars.FindAsync(carId) ?? throw new NotFoundException($"Car with ID {carId} not exist."); car.CarStatusId = (CarStatusEnum)statusId; - _context.Cars.Update(car); - await _context.SaveChangesAsync(); + context.Cars.Update(car); + await context.SaveChangesAsync(); } public async Task Delete(int carId) { - var car = await _context.Cars.FindAsync(carId) ?? throw new NotFoundException($"Car with ID {carId} not exist."); + var car = await context.Cars.FindAsync(carId) ?? throw new NotFoundException($"Car with ID {carId} not exist."); - _context.Cars.Remove(car); - await _context.SaveChangesAsync(); + context.Cars.Remove(car); + await context.SaveChangesAsync(); } } diff --git a/AutoHub.BusinessLogic/Services/EmailService.cs b/AutoHub.BusinessLogic/Services/EmailService.cs index 2839050..f3fc751 100644 --- a/AutoHub.BusinessLogic/Services/EmailService.cs +++ b/AutoHub.BusinessLogic/Services/EmailService.cs @@ -9,14 +9,9 @@ namespace AutoHub.BusinessLogic.Services; -public class EmailService : IEmailService +public class EmailService(IOptions mailConfiguration) : IEmailService { - private readonly MailConfiguration _mailConfiguration; - - public EmailService(IOptions mailConfiguration) - { - _mailConfiguration = mailConfiguration.Value; - } + private readonly MailConfiguration _mailConfiguration = mailConfiguration.Value; public async Task SendEmail(SendMailRequest mailRequest) { diff --git a/AutoHub.BusinessLogic/Services/LotService.cs b/AutoHub.BusinessLogic/Services/LotService.cs index 9f62137..1c683bc 100644 --- a/AutoHub.BusinessLogic/Services/LotService.cs +++ b/AutoHub.BusinessLogic/Services/LotService.cs @@ -18,24 +18,14 @@ namespace AutoHub.BusinessLogic.Services; -public class LotService : ILotService +public class LotService(AutoHubContext context, IMapper mapper, UserManager userManager) + : ILotService { - private readonly AutoHubContext _context; - private readonly IMapper _mapper; - private readonly UserManager _userManager; - - public LotService(AutoHubContext context, IMapper mapper, UserManager userManager) - { - _context = context; - _mapper = mapper; - _userManager = userManager; - } - public async Task> GetAll(PaginationParameters paginationParameters) { List lots; var limit = paginationParameters.Limit ?? DefaultPaginationValues.DefaultLimit; - var query = _context.Lots + var query = context.Lots .OrderBy(x => x.LotId) .Take(limit) .AsQueryable(); @@ -55,17 +45,17 @@ public async Task> GetAll(PaginationParameters pagin lots = await query.ToListAsync(); } - var mappedLots = _mapper.Map>(lots).ToList(); + var mappedLots = mapper.Map>(lots).ToList(); foreach (var lot in mappedLots) { - var creatorRoles = await _userManager.GetRolesAsync(lots.Single(x => x.CreatorId == lot.Creator.UserId).Creator); + var creatorRoles = await userManager.GetRolesAsync(lots.Single(x => x.CreatorId == lot.Creator.UserId).Creator); lot.Creator.UserRoles = creatorRoles; if (lot.Winner is not null) { var winnerRoles = - await _userManager.GetRolesAsync(lots.Single(x => x.WinnerId == lot.Winner.UserId).Winner); + await userManager.GetRolesAsync(lots.Single(x => x.WinnerId == lot.Winner.UserId).Winner); lot.Winner.UserRoles = winnerRoles; } } @@ -75,8 +65,8 @@ public async Task> GetAll(PaginationParameters pagin public async Task> GetRequiredOfDeterminingWinner() { - var lotsToDefineWinner = await _context.Lots.Where(x => x.EndTime.HasValue && x.EndTime.Value < DateTime.UtcNow && x.Winner == null).ToListAsync(); - var mappedLots = _mapper.Map>(lotsToDefineWinner); + var lotsToDefineWinner = await context.Lots.Where(x => x.EndTime.HasValue && x.EndTime.Value < DateTime.UtcNow && x.Winner == null).ToListAsync(); + var mappedLots = mapper.Map>(lotsToDefineWinner); return mappedLots; } @@ -84,7 +74,7 @@ public async Task> GetInProgress(PaginationParameter { List lots; var limit = paginationParameters.Limit ?? DefaultPaginationValues.DefaultLimit; - var query = _context.Lots + var query = context.Lots .OrderBy(x => x.LotId) .Where(x => x.LotStatusId == LotStatusEnum.InProgress) .Take(limit) @@ -105,28 +95,28 @@ public async Task> GetInProgress(PaginationParameter lots = await query.ToListAsync(); } - var mappedLots = _mapper.Map>(lots); + var mappedLots = mapper.Map>(lots); return mappedLots; } public async Task GetById(int lotId) { - var lot = await _context.Lots.FindAsync(lotId) ?? throw new NotFoundException($"Lot with ID {lotId} not exist."); + var lot = await context.Lots.FindAsync(lotId) ?? throw new NotFoundException($"Lot with ID {lotId} not exist."); - var mappedLot = _mapper.Map(lot); + var mappedLot = mapper.Map(lot); return mappedLot; } public async Task Create(LotCreateRequestDTO createLotDTO) { - var lot = _mapper.Map(createLotDTO); + var lot = mapper.Map(createLotDTO); lot.LotStatusId = LotStatusEnum.New; lot.StartTime = DateTime.UtcNow; lot.EndTime = lot.StartTime.AddDays(createLotDTO.DurationInDays); - await _context.Lots.AddAsync(lot); - await _context.SaveChangesAsync(); + await context.Lots.AddAsync(lot); + await context.SaveChangesAsync(); } public async Task Update(int lotId, LotUpdateRequestDTO updateLotDTO) @@ -136,7 +126,7 @@ public async Task Update(int lotId, LotUpdateRequestDTO updateLotDTO) throw new EntityValidationException($"Incorrect {nameof(LotStatus.LotStatusId)} value."); } - var lot = await _context.Lots.FindAsync(lotId) ?? throw new NotFoundException($"Lot with ID {lotId} not exist."); + var lot = await context.Lots.FindAsync(lotId) ?? throw new NotFoundException($"Lot with ID {lotId} not exist."); if (updateLotDTO.LotStatusId.HasValue) { @@ -145,7 +135,7 @@ public async Task Update(int lotId, LotUpdateRequestDTO updateLotDTO) if (updateLotDTO.WinnerId.HasValue) { - lot.Winner = await _context.Users.FindAsync(updateLotDTO.WinnerId) ?? throw new NotFoundException($"User with ID {updateLotDTO.WinnerId} not exist."); + lot.Winner = await context.Users.FindAsync(updateLotDTO.WinnerId) ?? throw new NotFoundException($"User with ID {updateLotDTO.WinnerId} not exist."); } if (updateLotDTO.DurationInDays.HasValue) @@ -153,8 +143,8 @@ public async Task Update(int lotId, LotUpdateRequestDTO updateLotDTO) lot.EndTime = lot.StartTime.AddDays(updateLotDTO.DurationInDays.Value); } - _context.Lots.Update(lot); - await _context.SaveChangesAsync(); + context.Lots.Update(lot); + await context.SaveChangesAsync(); } public async Task UpdateStatus(int lotId, int statusId) @@ -164,19 +154,19 @@ public async Task UpdateStatus(int lotId, int statusId) throw new EntityValidationException($"Incorrect {nameof(LotStatus.LotStatusId)} value."); } - var lot = await _context.Lots.FindAsync(lotId) ?? throw new NotFoundException($"Lot with ID {lotId} not exist."); + var lot = await context.Lots.FindAsync(lotId) ?? throw new NotFoundException($"Lot with ID {lotId} not exist."); lot.LotStatusId = (LotStatusEnum)statusId; - _context.Lots.Update(lot); - await _context.SaveChangesAsync(); + context.Lots.Update(lot); + await context.SaveChangesAsync(); } public async Task Delete(int lotId) { - var lot = await _context.Lots.FindAsync(lotId) ?? throw new NotFoundException($"Lot with ID {lotId} not exist."); + var lot = await context.Lots.FindAsync(lotId) ?? throw new NotFoundException($"Lot with ID {lotId} not exist."); - _context.Lots.Remove(lot); - await _context.SaveChangesAsync(); + context.Lots.Remove(lot); + await context.SaveChangesAsync(); } } diff --git a/AutoHub.BusinessLogic/Services/UserService.cs b/AutoHub.BusinessLogic/Services/UserService.cs index 6d06edf..72466b0 100644 --- a/AutoHub.BusinessLogic/Services/UserService.cs +++ b/AutoHub.BusinessLogic/Services/UserService.cs @@ -19,30 +19,22 @@ namespace AutoHub.BusinessLogic.Services; -public class UserService : IUserService +public class UserService( + AutoHubContext context, + IMapper mapper, + IAuthenticationService authService, + IEmailService emailService, + UserManager userManager, + SignInManager signManager) + : IUserService { - private readonly IAuthenticationService _authService; - private readonly IEmailService _emailService; - private readonly UserManager _userManager; - private readonly SignInManager _signManager; - private readonly AutoHubContext _context; - private readonly IMapper _mapper; - - public UserService(AutoHubContext context, IMapper mapper, IAuthenticationService authService, IEmailService emailService, - UserManager userManager, SignInManager signManager) - { - _context = context; - _mapper = mapper; - _authService = authService ?? throw new ArgumentNullException(nameof(authService)); - _emailService = emailService ?? throw new ArgumentNullException(nameof(emailService)); - _userManager = userManager; - _signManager = signManager; - } + private readonly IAuthenticationService _authService = authService ?? throw new ArgumentNullException(nameof(authService)); + private readonly IEmailService _emailService = emailService ?? throw new ArgumentNullException(nameof(emailService)); public async Task> GetAll(PaginationParameters paginationParameters) { var limit = paginationParameters.Limit ?? DefaultPaginationValues.DefaultLimit; - var query = _context.Users.OrderBy(x => x.Id).AsQueryable(); + var query = context.Users.OrderBy(x => x.Id).AsQueryable(); List users; if (paginationParameters.After is not null && paginationParameters.Before is null) @@ -60,11 +52,11 @@ public async Task> GetAll(PaginationParameters pagi users = await query.Take(limit).ToListAsync(); } - var mappedUsers = _mapper.Map>(users).ToList(); + var mappedUsers = mapper.Map>(users).ToList(); foreach (var dto in mappedUsers) { - dto.UserRoles = await _userManager.GetRolesAsync(users.Single(x => x.Id == dto.UserId)); + dto.UserRoles = await userManager.GetRolesAsync(users.Single(x => x.Id == dto.UserId)); } return mappedUsers; @@ -72,34 +64,34 @@ public async Task> GetAll(PaginationParameters pagi public async Task GetById(int userId) { - var user = await _context.Users.FindAsync(userId) ?? throw new NotFoundException($"User with ID {userId} not exist."); + var user = await context.Users.FindAsync(userId) ?? throw new NotFoundException($"User with ID {userId} not exist."); - var mappedUser = _mapper.Map(user); - mappedUser.UserRoles = await _userManager.GetRolesAsync(user); + var mappedUser = mapper.Map(user); + mappedUser.UserRoles = await userManager.GetRolesAsync(user); return mappedUser; } public async Task GetByEmail(string email) { - var user = await _userManager.FindByEmailAsync(email) ?? throw new NotFoundException($"User with E-Mail {email} not exist."); + var user = await userManager.FindByEmailAsync(email) ?? throw new NotFoundException($"User with E-Mail {email} not exist."); - var mappedUser = _mapper.Map(user); - mappedUser.UserRoles = await _userManager.GetRolesAsync(user); + var mappedUser = mapper.Map(user); + mappedUser.UserRoles = await userManager.GetRolesAsync(user); return mappedUser; } public async Task Login(UserLoginRequestDTO userModel) { - var user = await _userManager.FindByNameAsync(userModel.Username) ?? throw new NotFoundException($"User with username {userModel.Username} not found."); + var user = await userManager.FindByNameAsync(userModel.Username) ?? throw new NotFoundException($"User with username {userModel.Username} not found."); if (user.EmailConfirmed.Equals(false)) { throw new LoginFailedException("Please confirm registration via link in your email."); } - var signInResult = await _signManager.PasswordSignInAsync(userModel.Username, userModel.Password, userModel.RememberMe, false); + var signInResult = await signManager.PasswordSignInAsync(userModel.Username, userModel.Password, userModel.RememberMe, false); if (signInResult.Succeeded.Equals(false)) { @@ -119,31 +111,31 @@ public async Task Login(UserLoginRequestDTO userModel) public async Task Register(UserRegisterRequestDTO registerUserDTO) { - if (await _userManager.FindByEmailAsync(registerUserDTO.Email) is not null) + if (await userManager.FindByEmailAsync(registerUserDTO.Email) is not null) { throw new RegistrationFailedException($"User with E-Mail ({registerUserDTO.Email}) already exists."); } - if (await _userManager.FindByNameAsync(registerUserDTO.Username) is not null) + if (await userManager.FindByNameAsync(registerUserDTO.Username) is not null) { throw new RegistrationFailedException($"User with username ({registerUserDTO.Username}) already exists."); } - var newUser = _mapper.Map(registerUserDTO); + var newUser = mapper.Map(registerUserDTO); newUser.RegistrationTime = DateTime.UtcNow; newUser.SecurityStamp = Guid.NewGuid().ToString(); try { - var result = await _userManager.CreateAsync(newUser, registerUserDTO.Password); + var result = await userManager.CreateAsync(newUser, registerUserDTO.Password); if (result.Succeeded.Equals(true)) { - var confirmationCode = await _userManager.GenerateEmailConfirmationTokenAsync(newUser); + var confirmationCode = await userManager.GenerateEmailConfirmationTokenAsync(newUser); confirmationCode = Base64Helper.Encode(confirmationCode); - await _userManager.ConfirmEmailAsync(newUser, Base64Helper.Decode(confirmationCode)); + await userManager.ConfirmEmailAsync(newUser, Base64Helper.Decode(confirmationCode)); await _emailService.SendEmail(new SendMailRequest { @@ -154,8 +146,8 @@ await _emailService.SendEmail(new SendMailRequest $"{confirmationCode}." }); - await _userManager.AddToRoleAsync(newUser, AuthorizationRoles.Customer); - await _signManager.SignInAsync(newUser, isPersistent: false); + await userManager.AddToRoleAsync(newUser, AuthorizationRoles.Customer); + await signManager.SignInAsync(newUser, isPersistent: false); } else { @@ -164,14 +156,14 @@ await _emailService.SendEmail(new SendMailRequest } catch (Exception) { - await _userManager.DeleteAsync(newUser); + await userManager.DeleteAsync(newUser); throw; } } public async Task Update(int userId, UserUpdateRequestDTO updateUserDTO) { - var user = await _context.Users.FindAsync(userId) ?? throw new NotFoundException($"User with ID {userId} not exist."); + var user = await context.Users.FindAsync(userId) ?? throw new NotFoundException($"User with ID {userId} not exist."); user.FirstName = updateUserDTO.FirstName; user.LastName = updateUserDTO.LastName; @@ -179,8 +171,8 @@ public async Task Update(int userId, UserUpdateRequestDTO updateUserDTO) user.Email = updateUserDTO.Email; user.PhoneNumber = updateUserDTO.PhoneNumber; - _context.Users.Update(user); - await _context.SaveChangesAsync(); + context.Users.Update(user); + await context.SaveChangesAsync(); } public async Task AddToRole(int userId, int roleId) @@ -190,17 +182,17 @@ public async Task AddToRole(int userId, int roleId) throw new EntityValidationException("Incorrect user role ID"); } - var user = await _context.Users.FindAsync(userId) ?? throw new NotFoundException($"User with ID {userId} not exist."); + var user = await context.Users.FindAsync(userId) ?? throw new NotFoundException($"User with ID {userId} not exist."); - var userRoles = await _userManager.GetRolesAsync(user); + var userRoles = await userManager.GetRolesAsync(user); if (userRoles.Contains(Enum.GetName(typeof(UserRoleEnum), roleId))) { throw new DuplicateException($"User already have {(UserRoleEnum)roleId} role."); } - await _userManager.AddToRoleAsync(user, Enum.GetName(typeof(UserRoleEnum), roleId)); - await _context.SaveChangesAsync(); + await userManager.AddToRoleAsync(user, Enum.GetName(typeof(UserRoleEnum), roleId)); + await context.SaveChangesAsync(); } public async Task RemoveFromRole(int userId, int roleId) @@ -210,26 +202,26 @@ public async Task RemoveFromRole(int userId, int roleId) throw new EntityValidationException("Incorrect user role ID"); } - var user = await _context.Users.FindAsync(userId) ?? throw new NotFoundException($"User with ID {userId} not exist."); + var user = await context.Users.FindAsync(userId) ?? throw new NotFoundException($"User with ID {userId} not exist."); - var userRoles = await _userManager.GetRolesAsync(user); + var userRoles = await userManager.GetRolesAsync(user); if (userRoles.Contains(Enum.GetName(typeof(UserRoleEnum), roleId)).Equals(false)) { throw new NotFoundException($"User don`t have {(UserRoleEnum)roleId} role."); } - await _userManager.RemoveFromRoleAsync(user, Enum.GetName(typeof(UserRoleEnum), roleId)); - await _context.SaveChangesAsync(); + await userManager.RemoveFromRoleAsync(user, Enum.GetName(typeof(UserRoleEnum), roleId)); + await context.SaveChangesAsync(); } public async Task Delete(int userId) { - var user = await _context.Users.FindAsync(userId) ?? throw new NotFoundException($"User with ID {userId} not exist."); + var user = await context.Users.FindAsync(userId) ?? throw new NotFoundException($"User with ID {userId} not exist."); - _context.Users.Remove(user); - await _context.SaveChangesAsync(); + context.Users.Remove(user); + await context.SaveChangesAsync(); } - public async Task Logout() => await _signManager.SignOutAsync(); + public async Task Logout() => await signManager.SignOutAsync(); } \ No newline at end of file diff --git a/AutoHub.DataAccess/AutoHub.DataAccess.csproj b/AutoHub.DataAccess/AutoHub.DataAccess.csproj index 207af58..c3ff5d9 100644 --- a/AutoHub.DataAccess/AutoHub.DataAccess.csproj +++ b/AutoHub.DataAccess/AutoHub.DataAccess.csproj @@ -6,21 +6,22 @@ - - - + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/AutoHub.DataAccess/AutoHubContext.cs b/AutoHub.DataAccess/AutoHubContext.cs index 5c8c115..5fe88fa 100644 --- a/AutoHub.DataAccess/AutoHubContext.cs +++ b/AutoHub.DataAccess/AutoHubContext.cs @@ -29,7 +29,7 @@ public AutoHubContext(DbContextOptions options) : base(options) protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { - optionsBuilder.UseNpgsql("Host=localhost;Port=5432;Database=AutoHubDb;Username=postgres;Password=admin;Include Error Detail=true;"); + optionsBuilder.UseSqlServer("Server=autohub-db.database.windows.net,1433;Initial Catalog=AutoHubDb;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;Authentication=Active Directory Default"); optionsBuilder.UseLazyLoadingProxies(); optionsBuilder.LogTo(Console.WriteLine); } diff --git a/AutoHub.Domain/AutoHub.Domain.csproj b/AutoHub.Domain/AutoHub.Domain.csproj index a7b8af1..1850d1e 100644 --- a/AutoHub.Domain/AutoHub.Domain.csproj +++ b/AutoHub.Domain/AutoHub.Domain.csproj @@ -8,11 +8,11 @@ - - + + - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/AutoHub.Domain/Entities/Identity/ApplicationUser.cs b/AutoHub.Domain/Entities/Identity/ApplicationUser.cs index 5c98a01..caf39f0 100644 --- a/AutoHub.Domain/Entities/Identity/ApplicationUser.cs +++ b/AutoHub.Domain/Entities/Identity/ApplicationUser.cs @@ -3,15 +3,8 @@ namespace AutoHub.Domain.Entities.Identity; -public class ApplicationUser : IdentityUser +public sealed class ApplicationUser : IdentityUser { - public ApplicationUser() - { - UserBids = new List(); - UserLots = new List(); - VictoryLots = new List(); - } - [PersonalData, Required] public string FirstName { get; set; } @@ -22,9 +15,9 @@ public ApplicationUser() public DateTime RegistrationTime { get; set; } - public virtual IEnumerable UserBids { get; set; } + public IEnumerable UserBids { get; set; } = new List(); - public virtual IEnumerable UserLots { get; set; } + public IEnumerable UserLots { get; set; } = new List(); - public virtual IEnumerable VictoryLots { get; set; } + public IEnumerable VictoryLots { get; set; } = new List(); } diff --git a/AutoHub.Tests/AutoHub.Tests.csproj b/AutoHub.Tests/AutoHub.Tests.csproj index 6e6c69b..ecd791c 100644 --- a/AutoHub.Tests/AutoHub.Tests.csproj +++ b/AutoHub.Tests/AutoHub.Tests.csproj @@ -9,21 +9,21 @@ - - - - - - + + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive all From 19e422347db34e23cd60c6b0f7ab1f0f52b80be9 Mon Sep 17 00:00:00 2001 From: Nikita Reshetnik <45916288+grafanaKibana@users.noreply.github.com> Date: Fri, 11 Oct 2024 15:04:17 +0300 Subject: [PATCH 05/22] Add or update the Azure App Service build and deployment workflow config --- .github/workflows/develop_autohubapi.yml | 65 ++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 .github/workflows/develop_autohubapi.yml diff --git a/.github/workflows/develop_autohubapi.yml b/.github/workflows/develop_autohubapi.yml new file mode 100644 index 0000000..c44d0b9 --- /dev/null +++ b/.github/workflows/develop_autohubapi.yml @@ -0,0 +1,65 @@ +# Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy +# More GitHub Actions for Azure: https://github.com/Azure/actions + +name: Build and deploy ASP.Net Core app to Azure Web App - AutoHubAPI + +on: + push: + branches: + - develop + workflow_dispatch: + +jobs: + build: + runs-on: windows-latest + + steps: + - uses: actions/checkout@v4 + + - name: Set up .NET Core + uses: actions/setup-dotnet@v4 + with: + dotnet-version: '8.x' + + - name: Build with dotnet + run: dotnet build --configuration Release + + - name: dotnet publish + run: dotnet publish -c Release -o ${{env.DOTNET_ROOT}}/myapp + + - name: Upload artifact for deployment job + uses: actions/upload-artifact@v4 + with: + name: .net-app + path: ${{env.DOTNET_ROOT}}/myapp + + deploy: + runs-on: windows-latest + needs: build + environment: + name: 'Production' + url: ${{ steps.deploy-to-webapp.outputs.webapp-url }} + permissions: + id-token: write #This is required for requesting the JWT + + steps: + - name: Download artifact from build job + uses: actions/download-artifact@v4 + with: + name: .net-app + + - name: Login to Azure + uses: azure/login@v2 + with: + client-id: ${{ secrets.AZUREAPPSERVICE_CLIENTID_5BD849A4FE6E4C0DB7AD0EB5E846624D }} + tenant-id: ${{ secrets.AZUREAPPSERVICE_TENANTID_178D5841557B44B6846E2B87FE48DD59 }} + subscription-id: ${{ secrets.AZUREAPPSERVICE_SUBSCRIPTIONID_028CAC2C085347419D18855B1FF0AC4C }} + + - name: Deploy to Azure Web App + id: deploy-to-webapp + uses: azure/webapps-deploy@v3 + with: + app-name: 'AutoHubAPI' + slot-name: 'Production' + package: . + \ No newline at end of file From 99ac7dc7ea5352e6a7582fcd84c8df538a7f5792 Mon Sep 17 00:00:00 2001 From: nikitareshetnik Date: Fri, 11 Oct 2024 15:18:22 +0300 Subject: [PATCH 06/22] Fixed bug with app user --- AutoHub.API/Program.cs | 2 +- AutoHub.Domain/Entities/Identity/ApplicationUser.cs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/AutoHub.API/Program.cs b/AutoHub.API/Program.cs index aae3671..75b663e 100644 --- a/AutoHub.API/Program.cs +++ b/AutoHub.API/Program.cs @@ -49,12 +49,12 @@ } app.UseDeveloperExceptionPage(); + app.UseHttpsRedirection(); } app.UseSwaggerDocumentation(); app.UseRedocDocumentation(); app.UseMiddleware(); -app.UseHttpsRedirection(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); diff --git a/AutoHub.Domain/Entities/Identity/ApplicationUser.cs b/AutoHub.Domain/Entities/Identity/ApplicationUser.cs index caf39f0..bc9c4bc 100644 --- a/AutoHub.Domain/Entities/Identity/ApplicationUser.cs +++ b/AutoHub.Domain/Entities/Identity/ApplicationUser.cs @@ -3,7 +3,7 @@ namespace AutoHub.Domain.Entities.Identity; -public sealed class ApplicationUser : IdentityUser +public class ApplicationUser : IdentityUser { [PersonalData, Required] public string FirstName { get; set; } @@ -15,9 +15,9 @@ public sealed class ApplicationUser : IdentityUser public DateTime RegistrationTime { get; set; } - public IEnumerable UserBids { get; set; } = new List(); + public virtual IEnumerable UserBids { get; set; } = new List(); - public IEnumerable UserLots { get; set; } = new List(); + public virtual IEnumerable UserLots { get; set; } = new List(); - public IEnumerable VictoryLots { get; set; } = new List(); + public virtual IEnumerable VictoryLots { get; set; } = new List(); } From 7ca8a562325071564d92eaedbda0103f81f53924 Mon Sep 17 00:00:00 2001 From: nikitareshetnik Date: Fri, 11 Oct 2024 15:26:33 +0300 Subject: [PATCH 07/22] Updated CI pipeline --- .github/workflows/develop_autohubapi.yml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/develop_autohubapi.yml b/.github/workflows/develop_autohubapi.yml index c44d0b9..876682e 100644 --- a/.github/workflows/develop_autohubapi.yml +++ b/.github/workflows/develop_autohubapi.yml @@ -19,7 +19,7 @@ jobs: - name: Set up .NET Core uses: actions/setup-dotnet@v4 with: - dotnet-version: '8.x' + dotnet-version: csharp/global.json - name: Build with dotnet run: dotnet build --configuration Release @@ -39,21 +39,21 @@ jobs: environment: name: 'Production' url: ${{ steps.deploy-to-webapp.outputs.webapp-url }} - permissions: - id-token: write #This is required for requesting the JWT + permissions: + id-token: write #This is required for requesting the JWT steps: - name: Download artifact from build job uses: actions/download-artifact@v4 with: name: .net-app - - - name: Login to Azure - uses: azure/login@v2 - with: - client-id: ${{ secrets.AZUREAPPSERVICE_CLIENTID_5BD849A4FE6E4C0DB7AD0EB5E846624D }} - tenant-id: ${{ secrets.AZUREAPPSERVICE_TENANTID_178D5841557B44B6846E2B87FE48DD59 }} - subscription-id: ${{ secrets.AZUREAPPSERVICE_SUBSCRIPTIONID_028CAC2C085347419D18855B1FF0AC4C }} + + - name: Login to Azure + uses: azure/login@v2 + with: + client-id: ${{ secrets.AZUREAPPSERVICE_CLIENTID_5BD849A4FE6E4C0DB7AD0EB5E846624D }} + tenant-id: ${{ secrets.AZUREAPPSERVICE_TENANTID_178D5841557B44B6846E2B87FE48DD59 }} + subscription-id: ${{ secrets.AZUREAPPSERVICE_SUBSCRIPTIONID_028CAC2C085347419D18855B1FF0AC4C }} - name: Deploy to Azure Web App id: deploy-to-webapp From c40e4d59fa68000ec52f58724e350eda619a7a08 Mon Sep 17 00:00:00 2001 From: nikitareshetnik Date: Fri, 11 Oct 2024 15:27:36 +0300 Subject: [PATCH 08/22] Fixed CI pipeline --- .github/workflows/develop_autohubapi.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/develop_autohubapi.yml b/.github/workflows/develop_autohubapi.yml index 876682e..39f8ee2 100644 --- a/.github/workflows/develop_autohubapi.yml +++ b/.github/workflows/develop_autohubapi.yml @@ -19,7 +19,7 @@ jobs: - name: Set up .NET Core uses: actions/setup-dotnet@v4 with: - dotnet-version: csharp/global.json + global-json-file: csharp/global.json - name: Build with dotnet run: dotnet build --configuration Release From 153282be0a610dc0e151041fec9c719fd560da81 Mon Sep 17 00:00:00 2001 From: nikitareshetnik Date: Fri, 11 Oct 2024 15:31:44 +0300 Subject: [PATCH 09/22] CI Change --- .github/workflows/develop_autohubapi.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/develop_autohubapi.yml b/.github/workflows/develop_autohubapi.yml index 39f8ee2..59def2c 100644 --- a/.github/workflows/develop_autohubapi.yml +++ b/.github/workflows/develop_autohubapi.yml @@ -17,9 +17,9 @@ jobs: - uses: actions/checkout@v4 - name: Set up .NET Core - uses: actions/setup-dotnet@v4 + uses: AutoHubAPI/setup-dotnet@v4 with: - global-json-file: csharp/global.json + dotnet-version: 8.x - name: Build with dotnet run: dotnet build --configuration Release From 4d942cd1c0905bec90a5c1fc501e067135ccd1ba Mon Sep 17 00:00:00 2001 From: nikitareshetnik Date: Fri, 11 Oct 2024 15:34:00 +0300 Subject: [PATCH 10/22] CI Updated --- .github/workflows/develop_autohubapi.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/develop_autohubapi.yml b/.github/workflows/develop_autohubapi.yml index 59def2c..490e947 100644 --- a/.github/workflows/develop_autohubapi.yml +++ b/.github/workflows/develop_autohubapi.yml @@ -17,9 +17,9 @@ jobs: - uses: actions/checkout@v4 - name: Set up .NET Core - uses: AutoHubAPI/setup-dotnet@v4 + uses: actions/setup-dotnet@v4 with: - dotnet-version: 8.x + global-json-file: "./AutoHubAPI/global.json" - name: Build with dotnet run: dotnet build --configuration Release From f207dd2e29d291fc358b960c9d105f6f0a70adb1 Mon Sep 17 00:00:00 2001 From: nikitareshetnik Date: Fri, 11 Oct 2024 15:35:40 +0300 Subject: [PATCH 11/22] CI --- .github/workflows/develop_autohubapi.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/develop_autohubapi.yml b/.github/workflows/develop_autohubapi.yml index 490e947..8060e62 100644 --- a/.github/workflows/develop_autohubapi.yml +++ b/.github/workflows/develop_autohubapi.yml @@ -19,7 +19,7 @@ jobs: - name: Set up .NET Core uses: actions/setup-dotnet@v4 with: - global-json-file: "./AutoHubAPI/global.json" + global-json-file: global.json - name: Build with dotnet run: dotnet build --configuration Release From 9f40cc164533edb5009ffadd8b5f45a8b0121f2a Mon Sep 17 00:00:00 2001 From: nikitareshetnik Date: Fri, 11 Oct 2024 15:48:40 +0300 Subject: [PATCH 12/22] Fixed global.json --- global.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/global.json b/global.json index f6ba4b7..b5b37b6 100644 --- a/global.json +++ b/global.json @@ -4,4 +4,4 @@ "rollForward": "latestMajor", "allowPrerelease": false } -} +} \ No newline at end of file From 9784030683d515755353dfefc969789f202abac4 Mon Sep 17 00:00:00 2001 From: nikitareshetnik Date: Fri, 11 Oct 2024 15:51:01 +0300 Subject: [PATCH 13/22] Updated ci name --- .../{develop_autohubapi.yml => ci.yml} | 128 +++++++++--------- 1 file changed, 64 insertions(+), 64 deletions(-) rename .github/workflows/{develop_autohubapi.yml => ci.yml} (96%) diff --git a/.github/workflows/develop_autohubapi.yml b/.github/workflows/ci.yml similarity index 96% rename from .github/workflows/develop_autohubapi.yml rename to .github/workflows/ci.yml index 8060e62..d40e54c 100644 --- a/.github/workflows/develop_autohubapi.yml +++ b/.github/workflows/ci.yml @@ -1,65 +1,65 @@ -# Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy -# More GitHub Actions for Azure: https://github.com/Azure/actions - -name: Build and deploy ASP.Net Core app to Azure Web App - AutoHubAPI - -on: - push: - branches: - - develop - workflow_dispatch: - -jobs: - build: - runs-on: windows-latest - - steps: - - uses: actions/checkout@v4 - - - name: Set up .NET Core - uses: actions/setup-dotnet@v4 - with: - global-json-file: global.json - - - name: Build with dotnet - run: dotnet build --configuration Release - - - name: dotnet publish - run: dotnet publish -c Release -o ${{env.DOTNET_ROOT}}/myapp - - - name: Upload artifact for deployment job - uses: actions/upload-artifact@v4 - with: - name: .net-app - path: ${{env.DOTNET_ROOT}}/myapp - - deploy: - runs-on: windows-latest - needs: build - environment: - name: 'Production' - url: ${{ steps.deploy-to-webapp.outputs.webapp-url }} - permissions: - id-token: write #This is required for requesting the JWT - - steps: - - name: Download artifact from build job - uses: actions/download-artifact@v4 - with: - name: .net-app - - - name: Login to Azure - uses: azure/login@v2 - with: - client-id: ${{ secrets.AZUREAPPSERVICE_CLIENTID_5BD849A4FE6E4C0DB7AD0EB5E846624D }} - tenant-id: ${{ secrets.AZUREAPPSERVICE_TENANTID_178D5841557B44B6846E2B87FE48DD59 }} - subscription-id: ${{ secrets.AZUREAPPSERVICE_SUBSCRIPTIONID_028CAC2C085347419D18855B1FF0AC4C }} - - - name: Deploy to Azure Web App - id: deploy-to-webapp - uses: azure/webapps-deploy@v3 - with: - app-name: 'AutoHubAPI' - slot-name: 'Production' - package: . +# Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy +# More GitHub Actions for Azure: https://github.com/Azure/actions + +name: Build and deploy ASP.Net Core app to Azure Web App - AutoHubAPI + +on: + push: + branches: + - develop + workflow_dispatch: + +jobs: + build: + runs-on: windows-latest + + steps: + - uses: actions/checkout@v4 + + - name: Set up .NET Core + uses: actions/setup-dotnet@v4 + with: + global-json-file: global.json + + - name: Build with dotnet + run: dotnet build --configuration Release + + - name: dotnet publish + run: dotnet publish -c Release -o ${{env.DOTNET_ROOT}}/myapp + + - name: Upload artifact for deployment job + uses: actions/upload-artifact@v4 + with: + name: .net-app + path: ${{env.DOTNET_ROOT}}/myapp + + deploy: + runs-on: windows-latest + needs: build + environment: + name: 'Production' + url: ${{ steps.deploy-to-webapp.outputs.webapp-url }} + permissions: + id-token: write #This is required for requesting the JWT + + steps: + - name: Download artifact from build job + uses: actions/download-artifact@v4 + with: + name: .net-app + + - name: Login to Azure + uses: azure/login@v2 + with: + client-id: ${{ secrets.AZUREAPPSERVICE_CLIENTID_5BD849A4FE6E4C0DB7AD0EB5E846624D }} + tenant-id: ${{ secrets.AZUREAPPSERVICE_TENANTID_178D5841557B44B6846E2B87FE48DD59 }} + subscription-id: ${{ secrets.AZUREAPPSERVICE_SUBSCRIPTIONID_028CAC2C085347419D18855B1FF0AC4C }} + + - name: Deploy to Azure Web App + id: deploy-to-webapp + uses: azure/webapps-deploy@v3 + with: + app-name: 'AutoHubAPI' + slot-name: 'Production' + package: . \ No newline at end of file From bef6a64dc69964da89779762c1adc5e8184957f1 Mon Sep 17 00:00:00 2001 From: nikitareshetnik Date: Fri, 11 Oct 2024 15:56:25 +0300 Subject: [PATCH 14/22] Fix global.json --- global.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/global.json b/global.json index b5b37b6..9498eee 100644 --- a/global.json +++ b/global.json @@ -1,7 +1,6 @@ { "sdk": { "version": "8.0.0", - "rollForward": "latestMajor", - "allowPrerelease": false + "rollForward": "latestMajor" } } \ No newline at end of file From 87fe64fa4600bff8f6c3402d736b5bc916dc5dcc Mon Sep 17 00:00:00 2001 From: nikitareshetnik Date: Fri, 11 Oct 2024 15:59:16 +0300 Subject: [PATCH 15/22] Allow Prerelease --- global.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/global.json b/global.json index 9498eee..dad2db5 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,7 @@ { "sdk": { "version": "8.0.0", - "rollForward": "latestMajor" + "rollForward": "latestMajor", + "allowPrerelease": true } } \ No newline at end of file From 5797fe289281f046815f7a830f1302b770d9b0f3 Mon Sep 17 00:00:00 2001 From: nikitareshetnik Date: Fri, 11 Oct 2024 16:07:18 +0300 Subject: [PATCH 16/22] CI update --- .github/workflows/ci.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d40e54c..674dc37 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,9 +16,19 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Install jq + run: choco install jq + + - name: Read SDK version from global.json + id: read-sdk-version + run: | + SDK_VERSION=$(jq -r '.sdk.version' global.json | cut -d. -f1).X + echo "sdk_version=$SDK_VERSION" >> $GITHUB_ENV + - name: Set up .NET Core uses: actions/setup-dotnet@v4 with: + dotnet-version: ${{ steps.read-sdk-version.outputs.sdk_version }} global-json-file: global.json - name: Build with dotnet From 37f89ec37293f542e4d05644772e3bc39d39c208 Mon Sep 17 00:00:00 2001 From: nikitareshetnik Date: Fri, 11 Oct 2024 16:09:18 +0300 Subject: [PATCH 17/22] CI fix --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 674dc37..44367e1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,7 +22,7 @@ jobs: - name: Read SDK version from global.json id: read-sdk-version run: | - SDK_VERSION=$(jq -r '.sdk.version' global.json | cut -d. -f1).X + $SDK_VERSION = (jq -r '.sdk.version' global.json | cut -d. -f1) + ".X" echo "sdk_version=$SDK_VERSION" >> $GITHUB_ENV - name: Set up .NET Core From b46035561042e62ad0c3b8a70d8f2ce7e4b43f41 Mon Sep 17 00:00:00 2001 From: nikitareshetnik Date: Fri, 11 Oct 2024 16:17:25 +0300 Subject: [PATCH 18/22] Try of new CI --- .github/workflows/ci.yml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 44367e1..f063ba8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,14 +21,18 @@ jobs: - name: Read SDK version from global.json id: read-sdk-version + shell: pwsh run: | - $SDK_VERSION = (jq -r '.sdk.version' global.json | cut -d. -f1) + ".X" - echo "sdk_version=$SDK_VERSION" >> $GITHUB_ENV + $globalJson = Get-Content -Raw -Path global.json | ConvertFrom-Json + $sdkVersion = $globalJson.sdk.version + $majorVersion = $sdkVersion.Split('.')[0] + $sdkVersionModified = "$majorVersion.X" + Write-Host "sdk_version=$sdkVersionModified" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - name: Set up .NET Core uses: actions/setup-dotnet@v4 with: - dotnet-version: ${{ steps.read-sdk-version.outputs.sdk_version }} + dotnet-version: ${{ env.sdk_version }} global-json-file: global.json - name: Build with dotnet From 30e48ffd129030fd719ae54cd2deae7c31c64674 Mon Sep 17 00:00:00 2001 From: nikitareshetnik Date: Fri, 11 Oct 2024 16:23:30 +0300 Subject: [PATCH 19/22] CI --- .github/workflows/ci.yml | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f063ba8..91f21b5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,24 +16,10 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Install jq - run: choco install jq - - - name: Read SDK version from global.json - id: read-sdk-version - shell: pwsh - run: | - $globalJson = Get-Content -Raw -Path global.json | ConvertFrom-Json - $sdkVersion = $globalJson.sdk.version - $majorVersion = $sdkVersion.Split('.')[0] - $sdkVersionModified = "$majorVersion.X" - Write-Host "sdk_version=$sdkVersionModified" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - - name: Set up .NET Core uses: actions/setup-dotnet@v4 with: - dotnet-version: ${{ env.sdk_version }} - global-json-file: global.json + dotnet-version: "8.x" - name: Build with dotnet run: dotnet build --configuration Release From 4647c412010c2c47ed9cb9cd7e1d589701750269 Mon Sep 17 00:00:00 2001 From: nikitareshetnik Date: Fri, 11 Oct 2024 16:36:50 +0300 Subject: [PATCH 20/22] New CI --- .github/workflows/ci.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 91f21b5..34953d8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,14 +24,17 @@ jobs: - name: Build with dotnet run: dotnet build --configuration Release + - name: Run tests with dotnet + run: dotnet test -c Debug --no-build --no-restore + - name: dotnet publish - run: dotnet publish -c Release -o ${{env.DOTNET_ROOT}}/myapp + run: dotnet publish -c Release -o ./publish - name: Upload artifact for deployment job uses: actions/upload-artifact@v4 with: name: .net-app - path: ${{env.DOTNET_ROOT}}/myapp + path: ./publish deploy: runs-on: windows-latest @@ -61,5 +64,5 @@ jobs: with: app-name: 'AutoHubAPI' slot-name: 'Production' - package: . + package: ./publish \ No newline at end of file From 80824dc39b33daf26ef2dcefa1efdca2e426f6a7 Mon Sep 17 00:00:00 2001 From: nikitareshetnik Date: Fri, 11 Oct 2024 16:40:22 +0300 Subject: [PATCH 21/22] CI Fix --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 34953d8..a5e9fd7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,7 +25,7 @@ jobs: run: dotnet build --configuration Release - name: Run tests with dotnet - run: dotnet test -c Debug --no-build --no-restore + run: dotnet test -c Release --no-build --no-restore - name: dotnet publish run: dotnet publish -c Release -o ./publish From 417f0c0272c9015bd19d748dd0a8c642ec9a2f81 Mon Sep 17 00:00:00 2001 From: nikitareshetnik Date: Fri, 11 Oct 2024 16:44:31 +0300 Subject: [PATCH 22/22] Revert package name in CI --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a5e9fd7..8d91108 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,5 +64,5 @@ jobs: with: app-name: 'AutoHubAPI' slot-name: 'Production' - package: ./publish + package: . \ No newline at end of file