From 0153da31a904b27dc9002fd0bdd5a655e330c82f Mon Sep 17 00:00:00 2001 From: "M.F.M Fazrin" Date: Thu, 1 Jul 2021 16:48:31 +0530 Subject: [PATCH 1/2] Cleaned all unused Using Imports References --- Application/Behaviours/ValidationBehaviour.cs | 20 +- .../DTOs/Account/AuthenticationRequest.cs | 8 +- .../DTOs/Account/AuthenticationResponse.cs | 9 +- .../DTOs/Account/ForgotPasswordRequest.cs | 11 +- Application/DTOs/Account/RefreshToken.cs | 4 +- Application/DTOs/Account/RegisterRequest.cs | 30 +-- .../DTOs/Account/VerifyEmailRequest.cs | 24 +- Application/DTOs/Email/EmailRequest.cs | 8 +- Application/Enums/Roles.cs | 8 +- Application/Exceptions/ApiException.cs | 14 +- Application/Exceptions/ValidationException.cs | 18 +- .../CreateProduct/CreateProductCommand.cs | 14 +- .../CreateProductCommandValidator.cs | 15 +- .../DeleteProductByIdCommand.cs | 19 +- .../UpdateProduct/UpdateProductCommand.cs | 30 ++- .../GetAllProducts/GetAllProductsParameter.cs | 6 +- .../GetAllProducts/GetAllProductsQuery.cs | 26 ++- .../GetAllProducts/GetAllProductsViewModel.cs | 8 +- .../GetProductById/GetProductByIdQuery.cs | 16 +- Application/Interfaces/IAccountService.cs | 10 +- .../Interfaces/IAuthenticatedUserService.cs | 8 +- Application/Interfaces/IDateTimeService.cs | 4 +- Application/Interfaces/IEmailService.cs | 9 +- .../Interfaces/IGenericRepositoryAsync.cs | 6 +- .../Repositories/IProductRepositoryAsync.cs | 9 +- Application/Mappings/GeneralProfile.cs | 5 +- Application/Parameters/RequestParameter.cs | 22 +- Application/ServiceExtensions.cs | 11 +- Application/Wrappers/PagedResponse.cs | 26 +-- Application/Wrappers/Response.cs | 11 +- Domain/Common/AuditableBaseEntity.cs | 4 +- Domain/Common/BaseEntity.cs | 8 +- Domain/Entities/Product.cs | 5 +- Domain/Settings/JWTSettings.cs | 8 +- Domain/Settings/MailSettings.cs | 8 +- .../Contexts/IdentityContext.cs | 42 +--- .../Helpers/AuthenticationHelper.cs | 18 +- Infrastructure.Identity/Helpers/IpHelper.cs | 11 +- .../Models/ApplicationUser.cs | 11 +- .../Seeds/DefaultBasicUser.cs | 15 +- Infrastructure.Identity/Seeds/DefaultRoles.cs | 14 +- .../Seeds/DefaultSuperAdmin.cs | 17 +- Infrastructure.Identity/ServiceExtensions.cs | 46 ++-- .../Services/AccountService.cs | 218 ++++++++---------- .../Contexts/ApplicationDbContext.cs | 30 ++- .../Repositories/GenericRepositoryAsync.cs | 16 +- .../Repositories/ProductRepositoryAsync.cs | 9 +- .../ServiceRegistration.cs | 18 +- Infrastructure.Shared/ServiceRegistration.cs | 2 +- .../Services/DateTimeService.cs | 9 +- .../Services/EmailService.cs | 18 +- WebApi/CleanArchitecture.WebApi.xml | 13 +- WebApi/Controllers/AccountController.cs | 19 +- WebApi/Controllers/BaseApiController.cs | 3 +- WebApi/Controllers/MetaController.cs | 6 +- WebApi/Controllers/v1/ProductController.cs | 22 +- WebApi/Extensions/AppExtensions.cs | 12 +- WebApi/Extensions/ServiceExtensions.cs | 27 +-- WebApi/Middlewares/ErrorHandlerMiddleware.cs | 26 +-- WebApi/Models/Metadata.cs | 9 +- WebApi/Program.cs | 37 ++- WebApi/Properties/launchSettings.json | 2 +- WebApi/Services/AuthenticatedUserService.cs | 10 +- WebApi/Startup.cs | 12 +- WebApi/appsettings.json | 8 +- 65 files changed, 469 insertions(+), 673 deletions(-) diff --git a/Application/Behaviours/ValidationBehaviour.cs b/Application/Behaviours/ValidationBehaviour.cs index f14a4cd..8ac9259 100644 --- a/Application/Behaviours/ValidationBehaviour.cs +++ b/Application/Behaviours/ValidationBehaviour.cs @@ -1,9 +1,10 @@ -using FluentValidation; -using MediatR; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; +using FluentValidation; +using MediatR; +using ValidationException = Application.Exceptions.ValidationException; namespace Application.Behaviours { @@ -17,18 +18,21 @@ public ValidationBehavior(IEnumerable> validators) _validators = validators; } - public async Task Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate next) + public async Task Handle(TRequest request, CancellationToken cancellationToken, + RequestHandlerDelegate next) { if (_validators.Any()) { - var context = new FluentValidation.ValidationContext(request); - var validationResults = await Task.WhenAll(_validators.Select(v => v.ValidateAsync(context, cancellationToken))); + var context = new ValidationContext(request); + var validationResults = + await Task.WhenAll(_validators.Select(v => v.ValidateAsync(context, cancellationToken))); var failures = validationResults.SelectMany(r => r.Errors).Where(f => f != null).ToList(); if (failures.Count != 0) - throw new Exceptions.ValidationException(failures); + throw new ValidationException(failures); } + return await next(); } } -} +} \ No newline at end of file diff --git a/Application/DTOs/Account/AuthenticationRequest.cs b/Application/DTOs/Account/AuthenticationRequest.cs index 71eda9f..5d3f95f 100644 --- a/Application/DTOs/Account/AuthenticationRequest.cs +++ b/Application/DTOs/Account/AuthenticationRequest.cs @@ -1,12 +1,8 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace Application.DTOs.Account +namespace Application.DTOs.Account { public class AuthenticationRequest { public string Email { get; set; } public string Password { get; set; } } -} +} \ No newline at end of file diff --git a/Application/DTOs/Account/AuthenticationResponse.cs b/Application/DTOs/Account/AuthenticationResponse.cs index e22c7e5..6daf03e 100644 --- a/Application/DTOs/Account/AuthenticationResponse.cs +++ b/Application/DTOs/Account/AuthenticationResponse.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Text.Json.Serialization; namespace Application.DTOs.Account @@ -12,7 +11,7 @@ public class AuthenticationResponse public List Roles { get; set; } public bool IsVerified { get; set; } public string JWToken { get; set; } - [JsonIgnore] - public string RefreshToken { get; set; } + + [JsonIgnore] public string RefreshToken { get; set; } } -} +} \ No newline at end of file diff --git a/Application/DTOs/Account/ForgotPasswordRequest.cs b/Application/DTOs/Account/ForgotPasswordRequest.cs index e5006a6..f9cfe02 100644 --- a/Application/DTOs/Account/ForgotPasswordRequest.cs +++ b/Application/DTOs/Account/ForgotPasswordRequest.cs @@ -1,14 +1,9 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using System.Text; +using System.ComponentModel.DataAnnotations; namespace Application.DTOs.Account { public class ForgotPasswordRequest { - [Required] - [EmailAddress] - public string Email { get; set; } + [Required] [EmailAddress] public string Email { get; set; } } -} +} \ No newline at end of file diff --git a/Application/DTOs/Account/RefreshToken.cs b/Application/DTOs/Account/RefreshToken.cs index f7cca57..880a767 100644 --- a/Application/DTOs/Account/RefreshToken.cs +++ b/Application/DTOs/Account/RefreshToken.cs @@ -1,6 +1,4 @@ using System; -using System.Collections.Generic; -using System.Text; namespace Application.DTOs.Account { @@ -17,4 +15,4 @@ public class RefreshToken public string ReplacedByToken { get; set; } public bool IsActive => Revoked == null && !IsExpired; } -} +} \ No newline at end of file diff --git a/Application/DTOs/Account/RegisterRequest.cs b/Application/DTOs/Account/RegisterRequest.cs index 0f0284f..a6e5000 100644 --- a/Application/DTOs/Account/RegisterRequest.cs +++ b/Application/DTOs/Account/RegisterRequest.cs @@ -1,31 +1,19 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using System.Text; +using System.ComponentModel.DataAnnotations; namespace Application.DTOs.Account { public class RegisterRequest { - [Required] - public string FirstName { get; set; } + [Required] public string FirstName { get; set; } - [Required] - public string LastName { get; set; } + [Required] public string LastName { get; set; } - [Required] - [EmailAddress] - public string Email { get; set; } - [Required] - [MinLength(6)] - public string UserName { get; set; } + [Required] [EmailAddress] public string Email { get; set; } - [Required] - [MinLength(6)] - public string Password { get; set; } + [Required] [MinLength(6)] public string UserName { get; set; } - [Required] - [Compare("Password")] - public string ConfirmPassword { get; set; } + [Required] [MinLength(6)] public string Password { get; set; } + + [Required] [Compare("Password")] public string ConfirmPassword { get; set; } } -} +} \ No newline at end of file diff --git a/Application/DTOs/Account/VerifyEmailRequest.cs b/Application/DTOs/Account/VerifyEmailRequest.cs index d0513d4..e53e506 100644 --- a/Application/DTOs/Account/VerifyEmailRequest.cs +++ b/Application/DTOs/Account/VerifyEmailRequest.cs @@ -1,23 +1,15 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using System.Text; +using System.ComponentModel.DataAnnotations; namespace Application.DTOs.Account { public class ResetPasswordRequest { - [Required] - [EmailAddress] - public string Email { get; set; } - [Required] - public string Token { get; set; } - [Required] - [MinLength(6)] - public string Password { get; set; } + [Required] [EmailAddress] public string Email { get; set; } - [Required] - [Compare("Password")] - public string ConfirmPassword { get; set; } + [Required] public string Token { get; set; } + + [Required] [MinLength(6)] public string Password { get; set; } + + [Required] [Compare("Password")] public string ConfirmPassword { get; set; } } -} +} \ No newline at end of file diff --git a/Application/DTOs/Email/EmailRequest.cs b/Application/DTOs/Email/EmailRequest.cs index d8f0414..02be7ca 100644 --- a/Application/DTOs/Email/EmailRequest.cs +++ b/Application/DTOs/Email/EmailRequest.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace Application.DTOs.Email +namespace Application.DTOs.Email { public class EmailRequest { @@ -11,4 +7,4 @@ public class EmailRequest public string Body { get; set; } public string From { get; set; } } -} +} \ No newline at end of file diff --git a/Application/Enums/Roles.cs b/Application/Enums/Roles.cs index bc3602c..243cb33 100644 --- a/Application/Enums/Roles.cs +++ b/Application/Enums/Roles.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace Application.Enums +namespace Application.Enums { public enum Roles { @@ -11,4 +7,4 @@ public enum Roles Moderator, Basic } -} +} \ No newline at end of file diff --git a/Application/Exceptions/ApiException.cs b/Application/Exceptions/ApiException.cs index bacb18b..c405838 100644 --- a/Application/Exceptions/ApiException.cs +++ b/Application/Exceptions/ApiException.cs @@ -1,19 +1,21 @@ using System; -using System.Collections.Generic; using System.Globalization; -using System.Text; namespace Application.Exceptions { public class ApiException : Exception { - public ApiException() : base() { } + public ApiException() + { + } - public ApiException(string message) : base(message) { } + public ApiException(string message) : base(message) + { + } public ApiException(string message, params object[] args) - : base(String.Format(CultureInfo.CurrentCulture, message, args)) + : base(string.Format(CultureInfo.CurrentCulture, message, args)) { } } -} +} \ No newline at end of file diff --git a/Application/Exceptions/ValidationException.cs b/Application/Exceptions/ValidationException.cs index c38868e..5fa9c8f 100644 --- a/Application/Exceptions/ValidationException.cs +++ b/Application/Exceptions/ValidationException.cs @@ -1,8 +1,6 @@ -using FluentValidation.Results; -using System; +using System; using System.Collections.Generic; -using System.Linq; -using System.Text; +using FluentValidation.Results; namespace Application.Exceptions { @@ -12,15 +10,13 @@ public ValidationException() : base("One or more validation failures have occurr { Errors = new List(); } - public List Errors { get; } + public ValidationException(IEnumerable failures) : this() { - foreach (var failure in failures) - { - Errors.Add(failure.ErrorMessage); - } + foreach (var failure in failures) Errors.Add(failure.ErrorMessage); } - + + public List Errors { get; } } -} +} \ No newline at end of file diff --git a/Application/Features/Products/Commands/CreateProduct/CreateProductCommand.cs b/Application/Features/Products/Commands/CreateProduct/CreateProductCommand.cs index c49b80f..b4f4b87 100644 --- a/Application/Features/Products/Commands/CreateProduct/CreateProductCommand.cs +++ b/Application/Features/Products/Commands/CreateProduct/CreateProductCommand.cs @@ -1,24 +1,26 @@ -using Application.Interfaces.Repositories; +using System.Threading; +using System.Threading.Tasks; +using Application.Interfaces.Repositories; using Application.Wrappers; using AutoMapper; using Domain.Entities; using MediatR; -using System.Threading; -using System.Threading.Tasks; namespace Application.Features.Products.Commands.CreateProduct { - public partial class CreateProductCommand : IRequest> + public class CreateProductCommand : IRequest> { public string Name { get; set; } public string Barcode { get; set; } public string Description { get; set; } public decimal Rate { get; set; } } + public class CreateProductCommandHandler : IRequestHandler> { - private readonly IProductRepositoryAsync _productRepository; private readonly IMapper _mapper; + private readonly IProductRepositoryAsync _productRepository; + public CreateProductCommandHandler(IProductRepositoryAsync productRepository, IMapper mapper) { _productRepository = productRepository; @@ -32,4 +34,4 @@ public async Task> Handle(CreateProductCommand request, Cancellati return new Response(product.Id); } } -} +} \ No newline at end of file diff --git a/Application/Features/Products/Commands/CreateProduct/CreateProductCommandValidator.cs b/Application/Features/Products/Commands/CreateProduct/CreateProductCommandValidator.cs index 7fc7038..4f37426 100644 --- a/Application/Features/Products/Commands/CreateProduct/CreateProductCommandValidator.cs +++ b/Application/Features/Products/Commands/CreateProduct/CreateProductCommandValidator.cs @@ -1,13 +1,7 @@ -using Application.Interfaces.Repositories; -using Domain.Entities; -using FluentValidation; -using Microsoft.EntityFrameworkCore.Internal; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading; +using System.Threading; using System.Threading.Tasks; +using Application.Interfaces.Repositories; +using FluentValidation; namespace Application.Features.Products.Commands.CreateProduct { @@ -29,7 +23,6 @@ public CreateProductCommandValidator(IProductRepositoryAsync productRepository) .NotEmpty().WithMessage("{PropertyName} is required.") .NotNull() .MaximumLength(50).WithMessage("{PropertyName} must not exceed 50 characters."); - } private async Task IsUniqueBarcode(string barcode, CancellationToken cancellationToken) @@ -37,4 +30,4 @@ private async Task IsUniqueBarcode(string barcode, CancellationToken cance return await productRepository.IsUniqueBarcodeAsync(barcode); } } -} +} \ No newline at end of file diff --git a/Application/Features/Products/Commands/DeleteProductById/DeleteProductByIdCommand.cs b/Application/Features/Products/Commands/DeleteProductById/DeleteProductByIdCommand.cs index cb02622..ae2277d 100644 --- a/Application/Features/Products/Commands/DeleteProductById/DeleteProductByIdCommand.cs +++ b/Application/Features/Products/Commands/DeleteProductById/DeleteProductByIdCommand.cs @@ -1,32 +1,33 @@ -using Application.Exceptions; +using System.Threading; +using System.Threading.Tasks; +using Application.Exceptions; using Application.Interfaces.Repositories; using Application.Wrappers; using MediatR; -using System; -using System.Collections.Generic; -using System.Text; -using System.Threading; -using System.Threading.Tasks; namespace Application.Features.Products.Commands.DeleteProductById { public class DeleteProductByIdCommand : IRequest> { public int Id { get; set; } + public class DeleteProductByIdCommandHandler : IRequestHandler> { private readonly IProductRepositoryAsync _productRepository; + public DeleteProductByIdCommandHandler(IProductRepositoryAsync productRepository) { _productRepository = productRepository; } - public async Task> Handle(DeleteProductByIdCommand command, CancellationToken cancellationToken) + + public async Task> Handle(DeleteProductByIdCommand command, + CancellationToken cancellationToken) { var product = await _productRepository.GetByIdAsync(command.Id); - if (product == null) throw new ApiException($"Product Not Found."); + if (product == null) throw new ApiException("Product Not Found."); await _productRepository.DeleteAsync(product); return new Response(product.Id); } } } -} +} \ No newline at end of file diff --git a/Application/Features/Products/Commands/UpdateProduct/UpdateProductCommand.cs b/Application/Features/Products/Commands/UpdateProduct/UpdateProductCommand.cs index d3288aa..440c16b 100644 --- a/Application/Features/Products/Commands/UpdateProduct/UpdateProductCommand.cs +++ b/Application/Features/Products/Commands/UpdateProduct/UpdateProductCommand.cs @@ -1,12 +1,9 @@ -using Application.Exceptions; +using System.Threading; +using System.Threading.Tasks; +using Application.Exceptions; using Application.Interfaces.Repositories; using Application.Wrappers; using MediatR; -using System; -using System.Collections.Generic; -using System.Text; -using System.Threading; -using System.Threading.Tasks; namespace Application.Features.Products.Commands.UpdateProduct { @@ -16,30 +13,31 @@ public class UpdateProductCommand : IRequest> public string Name { get; set; } public string Description { get; set; } public decimal Rate { get; set; } + public class UpdateProductCommandHandler : IRequestHandler> { private readonly IProductRepositoryAsync _productRepository; + public UpdateProductCommandHandler(IProductRepositoryAsync productRepository) { _productRepository = productRepository; } + public async Task> Handle(UpdateProductCommand command, CancellationToken cancellationToken) { var product = await _productRepository.GetByIdAsync(command.Id); if (product == null) { - throw new ApiException($"Product Not Found."); - } - else - { - product.Name = command.Name; - product.Rate = command.Rate; - product.Description = command.Description; - await _productRepository.UpdateAsync(product); - return new Response(product.Id); + throw new ApiException("Product Not Found."); } + + product.Name = command.Name; + product.Rate = command.Rate; + product.Description = command.Description; + await _productRepository.UpdateAsync(product); + return new Response(product.Id); } } } -} +} \ No newline at end of file diff --git a/Application/Features/Products/Queries/GetAllProducts/GetAllProductsParameter.cs b/Application/Features/Products/Queries/GetAllProducts/GetAllProductsParameter.cs index a5ddb0f..cca316a 100644 --- a/Application/Features/Products/Queries/GetAllProducts/GetAllProductsParameter.cs +++ b/Application/Features/Products/Queries/GetAllProducts/GetAllProductsParameter.cs @@ -1,12 +1,8 @@ using Application.Filters; -using System; -using System.Collections.Generic; -using System.Text; namespace Application.Features.Products.Queries.GetAllProducts { public class GetAllProductsParameter : RequestParameter { - } -} +} \ No newline at end of file diff --git a/Application/Features/Products/Queries/GetAllProducts/GetAllProductsQuery.cs b/Application/Features/Products/Queries/GetAllProducts/GetAllProductsQuery.cs index 8428677..2e5acb8 100644 --- a/Application/Features/Products/Queries/GetAllProducts/GetAllProductsQuery.cs +++ b/Application/Features/Products/Queries/GetAllProducts/GetAllProductsQuery.cs @@ -1,13 +1,10 @@ -using Application.Filters; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; using Application.Interfaces.Repositories; using Application.Wrappers; using AutoMapper; using MediatR; -using System; -using System.Collections.Generic; -using System.Text; -using System.Threading; -using System.Threading.Tasks; namespace Application.Features.Products.Queries.GetAllProducts { @@ -16,22 +13,27 @@ public class GetAllProductsQuery : IRequest>> + + public class GetAllProductsQueryHandler : IRequestHandler>> { - private readonly IProductRepositoryAsync _productRepository; private readonly IMapper _mapper; + private readonly IProductRepositoryAsync _productRepository; + public GetAllProductsQueryHandler(IProductRepositoryAsync productRepository, IMapper mapper) { _productRepository = productRepository; _mapper = mapper; } - public async Task>> Handle(GetAllProductsQuery request, CancellationToken cancellationToken) + public async Task>> Handle(GetAllProductsQuery request, + CancellationToken cancellationToken) { var validFilter = _mapper.Map(request); - var product = await _productRepository.GetPagedReponseAsync(validFilter.PageNumber,validFilter.PageSize); + var product = await _productRepository.GetPagedReponseAsync(validFilter.PageNumber, validFilter.PageSize); var productViewModel = _mapper.Map>(product); - return new PagedResponse>(productViewModel, validFilter.PageNumber, validFilter.PageSize); + return new PagedResponse>(productViewModel, validFilter.PageNumber, + validFilter.PageSize); } } -} +} \ No newline at end of file diff --git a/Application/Features/Products/Queries/GetAllProducts/GetAllProductsViewModel.cs b/Application/Features/Products/Queries/GetAllProducts/GetAllProductsViewModel.cs index c52a51d..af58d78 100644 --- a/Application/Features/Products/Queries/GetAllProducts/GetAllProductsViewModel.cs +++ b/Application/Features/Products/Queries/GetAllProducts/GetAllProductsViewModel.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace Application.Features.Products.Queries.GetAllProducts +namespace Application.Features.Products.Queries.GetAllProducts { public class GetAllProductsViewModel { @@ -12,4 +8,4 @@ public class GetAllProductsViewModel public string Description { get; set; } public decimal Rate { get; set; } } -} +} \ No newline at end of file diff --git a/Application/Features/Products/Queries/GetProductById/GetProductByIdQuery.cs b/Application/Features/Products/Queries/GetProductById/GetProductByIdQuery.cs index 03883cb..c63c806 100644 --- a/Application/Features/Products/Queries/GetProductById/GetProductByIdQuery.cs +++ b/Application/Features/Products/Queries/GetProductById/GetProductByIdQuery.cs @@ -1,32 +1,32 @@ -using Application.Exceptions; +using System.Threading; +using System.Threading.Tasks; +using Application.Exceptions; using Application.Interfaces.Repositories; using Application.Wrappers; using Domain.Entities; using MediatR; -using System; -using System.Collections.Generic; -using System.Text; -using System.Threading; -using System.Threading.Tasks; namespace Application.Features.Products.Queries.GetProductById { public class GetProductByIdQuery : IRequest> { public int Id { get; set; } + public class GetProductByIdQueryHandler : IRequestHandler> { private readonly IProductRepositoryAsync _productRepository; + public GetProductByIdQueryHandler(IProductRepositoryAsync productRepository) { _productRepository = productRepository; } + public async Task> Handle(GetProductByIdQuery query, CancellationToken cancellationToken) { var product = await _productRepository.GetByIdAsync(query.Id); - if (product == null) throw new ApiException($"Product Not Found."); + if (product == null) throw new ApiException("Product Not Found."); return new Response(product); } } } -} +} \ No newline at end of file diff --git a/Application/Interfaces/IAccountService.cs b/Application/Interfaces/IAccountService.cs index 49bca7a..5a4af17 100644 --- a/Application/Interfaces/IAccountService.cs +++ b/Application/Interfaces/IAccountService.cs @@ -1,10 +1,6 @@ -using Application.DTOs.Account; +using System.Threading.Tasks; +using Application.DTOs.Account; using Application.Wrappers; -using Microsoft.Extensions.Primitives; -using System; -using System.Collections.Generic; -using System.Text; -using System.Threading.Tasks; namespace Application.Interfaces { @@ -16,4 +12,4 @@ public interface IAccountService Task ForgotPassword(ForgotPasswordRequest model, string origin); Task> ResetPassword(ResetPasswordRequest model); } -} +} \ No newline at end of file diff --git a/Application/Interfaces/IAuthenticatedUserService.cs b/Application/Interfaces/IAuthenticatedUserService.cs index 062d760..3dcbdda 100644 --- a/Application/Interfaces/IAuthenticatedUserService.cs +++ b/Application/Interfaces/IAuthenticatedUserService.cs @@ -1,11 +1,7 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace Application.Interfaces +namespace Application.Interfaces { public interface IAuthenticatedUserService { string UserId { get; } } -} +} \ No newline at end of file diff --git a/Application/Interfaces/IDateTimeService.cs b/Application/Interfaces/IDateTimeService.cs index 07727f3..ae4a68b 100644 --- a/Application/Interfaces/IDateTimeService.cs +++ b/Application/Interfaces/IDateTimeService.cs @@ -1,6 +1,4 @@ using System; -using System.Collections.Generic; -using System.Text; namespace Application.Interfaces { @@ -8,4 +6,4 @@ public interface IDateTimeService { DateTime NowUtc { get; } } -} +} \ No newline at end of file diff --git a/Application/Interfaces/IEmailService.cs b/Application/Interfaces/IEmailService.cs index 52796b7..7310a47 100644 --- a/Application/Interfaces/IEmailService.cs +++ b/Application/Interfaces/IEmailService.cs @@ -1,8 +1,5 @@ -using Application.DTOs.Email; -using System; -using System.Collections.Generic; -using System.Text; -using System.Threading.Tasks; +using System.Threading.Tasks; +using Application.DTOs.Email; namespace Application.Interfaces { @@ -10,4 +7,4 @@ public interface IEmailService { Task SendAsync(EmailRequest request); } -} +} \ No newline at end of file diff --git a/Application/Interfaces/IGenericRepositoryAsync.cs b/Application/Interfaces/IGenericRepositoryAsync.cs index e5147ec..848f578 100644 --- a/Application/Interfaces/IGenericRepositoryAsync.cs +++ b/Application/Interfaces/IGenericRepositoryAsync.cs @@ -1,6 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; +using System.Collections.Generic; using System.Threading.Tasks; namespace Application.Interfaces @@ -14,4 +12,4 @@ public interface IGenericRepositoryAsync where T : class Task UpdateAsync(T entity); Task DeleteAsync(T entity); } -} +} \ No newline at end of file diff --git a/Application/Interfaces/Repositories/IProductRepositoryAsync.cs b/Application/Interfaces/Repositories/IProductRepositoryAsync.cs index fbce55f..74aa44f 100644 --- a/Application/Interfaces/Repositories/IProductRepositoryAsync.cs +++ b/Application/Interfaces/Repositories/IProductRepositoryAsync.cs @@ -1,8 +1,5 @@ -using Domain.Entities; -using System; -using System.Collections.Generic; -using System.Text; -using System.Threading.Tasks; +using System.Threading.Tasks; +using Domain.Entities; namespace Application.Interfaces.Repositories { @@ -10,4 +7,4 @@ public interface IProductRepositoryAsync : IGenericRepositoryAsync { Task IsUniqueBarcodeAsync(string barcode); } -} +} \ No newline at end of file diff --git a/Application/Mappings/GeneralProfile.cs b/Application/Mappings/GeneralProfile.cs index 2dd0788..3cc304e 100644 --- a/Application/Mappings/GeneralProfile.cs +++ b/Application/Mappings/GeneralProfile.cs @@ -2,9 +2,6 @@ using Application.Features.Products.Queries.GetAllProducts; using AutoMapper; using Domain.Entities; -using System; -using System.Collections.Generic; -using System.Text; namespace Application.Mappings { @@ -17,4 +14,4 @@ public GeneralProfile() CreateMap(); } } -} +} \ No newline at end of file diff --git a/Application/Parameters/RequestParameter.cs b/Application/Parameters/RequestParameter.cs index 3fe2aa7..bf6572f 100644 --- a/Application/Parameters/RequestParameter.cs +++ b/Application/Parameters/RequestParameter.cs @@ -1,22 +1,20 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace Application.Filters +namespace Application.Filters { public class RequestParameter { - public int PageNumber { get; set; } - public int PageSize { get; set; } public RequestParameter() { - this.PageNumber = 1; - this.PageSize = 10; + PageNumber = 1; + PageSize = 10; } + public RequestParameter(int pageNumber, int pageSize) { - this.PageNumber = pageNumber < 1 ? 1 : pageNumber; - this.PageSize = pageSize > 10 ? 10 : pageSize; + PageNumber = pageNumber < 1 ? 1 : pageNumber; + PageSize = pageSize > 10 ? 10 : pageSize; } + + public int PageNumber { get; set; } + public int PageSize { get; set; } } -} +} \ No newline at end of file diff --git a/Application/ServiceExtensions.cs b/Application/ServiceExtensions.cs index f4f9cf8..c707cb3 100644 --- a/Application/ServiceExtensions.cs +++ b/Application/ServiceExtensions.cs @@ -1,13 +1,9 @@ -using Application.Behaviours; -using Application.Features.Products.Commands.CreateProduct; +using System.Reflection; +using Application.Behaviours; using AutoMapper; using FluentValidation; using MediatR; using Microsoft.Extensions.DependencyInjection; -using System; -using System.Collections.Generic; -using System.Reflection; -using System.Text; namespace Application { @@ -19,7 +15,6 @@ public static void AddApplicationLayer(this IServiceCollection services) services.AddValidatorsFromAssembly(Assembly.GetExecutingAssembly()); services.AddMediatR(Assembly.GetExecutingAssembly()); services.AddTransient(typeof(IPipelineBehavior<,>), typeof(ValidationBehavior<,>)); - } } -} +} \ No newline at end of file diff --git a/Application/Wrappers/PagedResponse.cs b/Application/Wrappers/PagedResponse.cs index f2e484d..cc866d9 100644 --- a/Application/Wrappers/PagedResponse.cs +++ b/Application/Wrappers/PagedResponse.cs @@ -1,22 +1,18 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace Application.Wrappers +namespace Application.Wrappers { public class PagedResponse : Response { - public int PageNumber { get; set; } - public int PageSize { get; set; } - public PagedResponse(T data, int pageNumber, int pageSize) { - this.PageNumber = pageNumber; - this.PageSize = pageSize; - this.Data = data; - this.Message = null; - this.Succeeded = true; - this.Errors = null; + PageNumber = pageNumber; + PageSize = pageSize; + Data = data; + Message = null; + Succeeded = true; + Errors = null; } + + public int PageNumber { get; set; } + public int PageSize { get; set; } } -} +} \ No newline at end of file diff --git a/Application/Wrappers/Response.cs b/Application/Wrappers/Response.cs index f1d5156..44043db 100644 --- a/Application/Wrappers/Response.cs +++ b/Application/Wrappers/Response.cs @@ -1,6 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; +using System.Collections.Generic; namespace Application.Wrappers { @@ -9,20 +7,23 @@ public class Response public Response() { } - public Response(T data,string message = null) + + public Response(T data, string message = null) { Succeeded = true; Message = message; Data = data; } + public Response(string message) { Succeeded = false; Message = message; } + public bool Succeeded { get; set; } public string Message { get; set; } public List Errors { get; set; } public T Data { get; set; } } -} +} \ No newline at end of file diff --git a/Domain/Common/AuditableBaseEntity.cs b/Domain/Common/AuditableBaseEntity.cs index 3baa8af..2f8a1d1 100644 --- a/Domain/Common/AuditableBaseEntity.cs +++ b/Domain/Common/AuditableBaseEntity.cs @@ -1,6 +1,4 @@ using System; -using System.Collections.Generic; -using System.Text; namespace Domain.Common { @@ -12,4 +10,4 @@ public abstract class AuditableBaseEntity public string LastModifiedBy { get; set; } public DateTime? LastModified { get; set; } } -} +} \ No newline at end of file diff --git a/Domain/Common/BaseEntity.cs b/Domain/Common/BaseEntity.cs index a01b261..a735e7a 100644 --- a/Domain/Common/BaseEntity.cs +++ b/Domain/Common/BaseEntity.cs @@ -1,11 +1,7 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace Domain.Common +namespace Domain.Common { public abstract class BaseEntity { public virtual int Id { get; set; } } -} +} \ No newline at end of file diff --git a/Domain/Entities/Product.cs b/Domain/Entities/Product.cs index 28e9074..5c39dfb 100644 --- a/Domain/Entities/Product.cs +++ b/Domain/Entities/Product.cs @@ -1,7 +1,4 @@ using Domain.Common; -using System; -using System.Collections.Generic; -using System.Text; namespace Domain.Entities { @@ -12,4 +9,4 @@ public class Product : AuditableBaseEntity public string Description { get; set; } public decimal Rate { get; set; } } -} +} \ No newline at end of file diff --git a/Domain/Settings/JWTSettings.cs b/Domain/Settings/JWTSettings.cs index a59c2a7..757a002 100644 --- a/Domain/Settings/JWTSettings.cs +++ b/Domain/Settings/JWTSettings.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace Domain.Settings +namespace Domain.Settings { public class JWTSettings { @@ -11,4 +7,4 @@ public class JWTSettings public string Audience { get; set; } public double DurationInMinutes { get; set; } } -} +} \ No newline at end of file diff --git a/Domain/Settings/MailSettings.cs b/Domain/Settings/MailSettings.cs index 302ce2e..d3bacac 100644 --- a/Domain/Settings/MailSettings.cs +++ b/Domain/Settings/MailSettings.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace Domain.Settings +namespace Domain.Settings { public class MailSettings { @@ -13,4 +9,4 @@ public class MailSettings public string SmtpPass { get; set; } public string DisplayName { get; set; } } -} +} \ No newline at end of file diff --git a/Infrastructure.Identity/Contexts/IdentityContext.cs b/Infrastructure.Identity/Contexts/IdentityContext.cs index cb64803..8518c98 100644 --- a/Infrastructure.Identity/Contexts/IdentityContext.cs +++ b/Infrastructure.Identity/Contexts/IdentityContext.cs @@ -2,9 +2,6 @@ using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; -using System; -using System.Collections.Generic; -using System.Text; namespace Infrastructure.Identity.Contexts { @@ -13,44 +10,23 @@ public class IdentityContext : IdentityDbContext public IdentityContext(DbContextOptions options) : base(options) { } + protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); builder.HasDefaultSchema("Identity"); - builder.Entity(entity => - { - entity.ToTable(name: "User"); - }); - - builder.Entity(entity => - { - entity.ToTable(name: "Role"); - }); - builder.Entity>(entity => - { - entity.ToTable("UserRoles"); - }); + builder.Entity(entity => { entity.ToTable("User"); }); - builder.Entity>(entity => - { - entity.ToTable("UserClaims"); - }); + builder.Entity(entity => { entity.ToTable("Role"); }); + builder.Entity>(entity => { entity.ToTable("UserRoles"); }); - builder.Entity>(entity => - { - entity.ToTable("UserLogins"); - }); + builder.Entity>(entity => { entity.ToTable("UserClaims"); }); - builder.Entity>(entity => - { - entity.ToTable("RoleClaims"); + builder.Entity>(entity => { entity.ToTable("UserLogins"); }); - }); + builder.Entity>(entity => { entity.ToTable("RoleClaims"); }); - builder.Entity>(entity => - { - entity.ToTable("UserTokens"); - }); + builder.Entity>(entity => { entity.ToTable("UserTokens"); }); } } -} +} \ No newline at end of file diff --git a/Infrastructure.Identity/Helpers/AuthenticationHelper.cs b/Infrastructure.Identity/Helpers/AuthenticationHelper.cs index 143bfe9..047fe3b 100644 --- a/Infrastructure.Identity/Helpers/AuthenticationHelper.cs +++ b/Infrastructure.Identity/Helpers/AuthenticationHelper.cs @@ -1,9 +1,8 @@ -using Microsoft.AspNetCore.Authentication.JwtBearer; +using System; +using System.Text; +using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.Extensions.DependencyInjection; using Microsoft.IdentityModel.Tokens; -using System; -using System.Collections.Generic; -using System.Text; namespace Infrastructure.Identity.Helpers { @@ -12,11 +11,10 @@ public class AuthenticationHelper public static void ConfigureService(IServiceCollection service, string Issuer, string Audience, string Key) { service.AddAuthentication(options => - { - options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; - options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; - }) - + { + options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; + options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; + }) .AddJwtBearer(o => { o.TokenValidationParameters = new TokenValidationParameters @@ -34,4 +32,4 @@ public static void ConfigureService(IServiceCollection service, string Issuer, s }); } } -} +} \ No newline at end of file diff --git a/Infrastructure.Identity/Helpers/IpHelper.cs b/Infrastructure.Identity/Helpers/IpHelper.cs index 5aadaf4..caa59f3 100644 --- a/Infrastructure.Identity/Helpers/IpHelper.cs +++ b/Infrastructure.Identity/Helpers/IpHelper.cs @@ -1,8 +1,5 @@ -using System; -using System.Collections.Generic; -using System.Net; +using System.Net; using System.Net.Sockets; -using System.Text; namespace Infrastructure.Identity.Helpers { @@ -12,13 +9,9 @@ public static string GetIpAddress() { var host = Dns.GetHostEntry(Dns.GetHostName()); foreach (var ip in host.AddressList) - { if (ip.AddressFamily == AddressFamily.InterNetwork) - { return ip.ToString(); - } - } return string.Empty; } } -} +} \ No newline at end of file diff --git a/Infrastructure.Identity/Models/ApplicationUser.cs b/Infrastructure.Identity/Models/ApplicationUser.cs index b36c50e..a21e06b 100644 --- a/Infrastructure.Identity/Models/ApplicationUser.cs +++ b/Infrastructure.Identity/Models/ApplicationUser.cs @@ -1,8 +1,6 @@ -using Application.DTOs.Account; +using System.Collections.Generic; +using Application.DTOs.Account; using Microsoft.AspNetCore.Identity; -using System; -using System.Collections.Generic; -using System.Text; namespace Infrastructure.Identity.Models { @@ -11,9 +9,10 @@ public class ApplicationUser : IdentityUser public string FirstName { get; set; } public string LastName { get; set; } public List RefreshTokens { get; set; } + public bool OwnsToken(string token) { - return this.RefreshTokens?.Find(x => x.Token == token) != null; + return RefreshTokens?.Find(x => x.Token == token) != null; } } -} +} \ No newline at end of file diff --git a/Infrastructure.Identity/Seeds/DefaultBasicUser.cs b/Infrastructure.Identity/Seeds/DefaultBasicUser.cs index c171100..6dbd62e 100644 --- a/Infrastructure.Identity/Seeds/DefaultBasicUser.cs +++ b/Infrastructure.Identity/Seeds/DefaultBasicUser.cs @@ -1,17 +1,15 @@ -using Application.Enums; +using System.Linq; +using System.Threading.Tasks; +using Application.Enums; using Infrastructure.Identity.Models; using Microsoft.AspNetCore.Identity; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Infrastructure.Identity.Seeds { public static class DefaultBasicUser { - public static async Task SeedAsync(UserManager userManager, RoleManager roleManager) + public static async Task SeedAsync(UserManager userManager, + RoleManager roleManager) { //Seed Default User var defaultUser = new ApplicationUser @@ -31,8 +29,7 @@ public static async Task SeedAsync(UserManager userManager, Rol await userManager.CreateAsync(defaultUser, "123Pa$$word!"); await userManager.AddToRoleAsync(defaultUser, Roles.Basic.ToString()); } - } } } -} +} \ No newline at end of file diff --git a/Infrastructure.Identity/Seeds/DefaultRoles.cs b/Infrastructure.Identity/Seeds/DefaultRoles.cs index 6a34142..e8ec9d2 100644 --- a/Infrastructure.Identity/Seeds/DefaultRoles.cs +++ b/Infrastructure.Identity/Seeds/DefaultRoles.cs @@ -1,16 +1,14 @@ -using Infrastructure.Identity.Models; -using Microsoft.AspNetCore.Identity; -using System; -using System.Collections.Generic; -using System.Text; -using System.Threading.Tasks; +using System.Threading.Tasks; using Application.Enums; +using Infrastructure.Identity.Models; +using Microsoft.AspNetCore.Identity; namespace Infrastructure.Identity.Seeds { public static class DefaultRoles { - public static async Task SeedAsync(UserManager userManager, RoleManager roleManager) + public static async Task SeedAsync(UserManager userManager, + RoleManager roleManager) { //Seed Roles await roleManager.CreateAsync(new IdentityRole(Roles.SuperAdmin.ToString())); @@ -19,4 +17,4 @@ public static async Task SeedAsync(UserManager userManager, Rol await roleManager.CreateAsync(new IdentityRole(Roles.Basic.ToString())); } } -} +} \ No newline at end of file diff --git a/Infrastructure.Identity/Seeds/DefaultSuperAdmin.cs b/Infrastructure.Identity/Seeds/DefaultSuperAdmin.cs index c97705b..738f092 100644 --- a/Infrastructure.Identity/Seeds/DefaultSuperAdmin.cs +++ b/Infrastructure.Identity/Seeds/DefaultSuperAdmin.cs @@ -1,19 +1,15 @@ -using Application.Enums; +using System.Linq; +using System.Threading.Tasks; +using Application.Enums; using Infrastructure.Identity.Models; using Microsoft.AspNetCore.Identity; -using Microsoft.Extensions.Logging; -using Org.BouncyCastle.Crypto.Prng.Drbg; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Infrastructure.Identity.Seeds { public static class DefaultSuperAdmin { - public static async Task SeedAsync(UserManager userManager, RoleManager roleManager) + public static async Task SeedAsync(UserManager userManager, + RoleManager roleManager) { //Seed Default User var defaultUser = new ApplicationUser @@ -36,8 +32,7 @@ public static async Task SeedAsync(UserManager userManager, Rol await userManager.AddToRoleAsync(defaultUser, Roles.Admin.ToString()); await userManager.AddToRoleAsync(defaultUser, Roles.SuperAdmin.ToString()); } - } } } -} +} \ No newline at end of file diff --git a/Infrastructure.Identity/ServiceExtensions.cs b/Infrastructure.Identity/ServiceExtensions.cs index 55d6603..3593538 100644 --- a/Infrastructure.Identity/ServiceExtensions.cs +++ b/Infrastructure.Identity/ServiceExtensions.cs @@ -1,9 +1,9 @@ -using Application.Exceptions; +using System; +using System.Text; using Application.Interfaces; using Application.Wrappers; using Domain.Settings; using Infrastructure.Identity.Contexts; -using Infrastructure.Identity.Helpers; using Infrastructure.Identity.Models; using Infrastructure.Identity.Services; using Microsoft.AspNetCore.Authentication.JwtBearer; @@ -14,10 +14,6 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.IdentityModel.Tokens; using Newtonsoft.Json; -using System; -using System.Reflection.Metadata.Ecma335; -using System.Text; -using System.Threading.Tasks; namespace Infrastructure.Identity { @@ -26,27 +22,28 @@ public static class ServiceExtensions public static void AddIdentityInfrastructure(this IServiceCollection services, IConfiguration configuration) { if (configuration.GetValue("UseInMemoryDatabase")) - { services.AddDbContext(options => options.UseInMemoryDatabase("IdentityDb")); - } else - { services.AddDbContext(options => - options.UseSqlServer( - configuration.GetConnectionString("IdentityConnection"), - b => b.MigrationsAssembly(typeof(IdentityContext).Assembly.FullName))); - } - services.AddIdentity().AddEntityFrameworkStores().AddDefaultTokenProviders(); + options.UseSqlServer( + configuration.GetConnectionString("IdentityConnection"), + b => b.MigrationsAssembly(typeof(IdentityContext).Assembly.FullName))); + services.AddIdentity().AddEntityFrameworkStores() + .AddDefaultTokenProviders(); + #region Services + services.AddTransient(); + #endregion + services.Configure(configuration.GetSection("JWTSettings")); services.AddAuthentication(options => - { - options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; - options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; - }) + { + options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; + options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; + }) .AddJwtBearer(o => { o.RequireHttpsMetadata = false; @@ -60,9 +57,10 @@ public static void AddIdentityInfrastructure(this IServiceCollection services, I ClockSkew = TimeSpan.Zero, ValidIssuer = configuration["JWTSettings:Issuer"], ValidAudience = configuration["JWTSettings:Audience"], - IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["JWTSettings:Key"])) + IssuerSigningKey = + new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["JWTSettings:Key"])) }; - o.Events = new JwtBearerEvents() + o.Events = new JwtBearerEvents { OnAuthenticationFailed = c => { @@ -83,11 +81,13 @@ public static void AddIdentityInfrastructure(this IServiceCollection services, I { context.Response.StatusCode = 403; context.Response.ContentType = "application/json"; - var result = JsonConvert.SerializeObject(new Response("You are not authorized to access this resource")); + var result = + JsonConvert.SerializeObject( + new Response("You are not authorized to access this resource")); return context.Response.WriteAsync(result); - }, + } }; }); } } -} +} \ No newline at end of file diff --git a/Infrastructure.Identity/Services/AccountService.cs b/Infrastructure.Identity/Services/AccountService.cs index 2a7704d..5ac7820 100644 --- a/Infrastructure.Identity/Services/AccountService.cs +++ b/Infrastructure.Identity/Services/AccountService.cs @@ -1,4 +1,14 @@ -using Application.DTOs.Account; +using System; +using System.Collections.Generic; +using System.IdentityModel.Tokens.Jwt; +using System.Linq; +using System.Security.Claims; +using System.Security.Cryptography; +using System.Text; +using System.Threading.Tasks; +using Application.DTOs.Account; +using Application.DTOs.Email; +using Application.Enums; using Application.Exceptions; using Application.Interfaces; using Application.Wrappers; @@ -6,38 +16,25 @@ using Infrastructure.Identity.Helpers; using Infrastructure.Identity.Models; using Microsoft.AspNetCore.Identity; -using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.WebUtilities; using Microsoft.Extensions.Options; using Microsoft.IdentityModel.Tokens; -using Org.BouncyCastle.Ocsp; -using System; -using System.Collections.Generic; -using System.IdentityModel.Tokens.Jwt; -using System.Linq; -using System.Net.Cache; -using System.Security.Claims; -using System.Security.Cryptography; -using System.Text; -using Application.Enums; -using System.Threading.Tasks; -using Microsoft.Extensions.Primitives; -using Application.DTOs.Email; namespace Infrastructure.Identity.Services { public class AccountService : IAccountService { - private readonly UserManager _userManager; - private readonly RoleManager _roleManager; - private readonly SignInManager _signInManager; + private readonly IDateTimeService _dateTimeService; private readonly IEmailService _emailService; private readonly JWTSettings _jwtSettings; - private readonly IDateTimeService _dateTimeService; - public AccountService(UserManager userManager, - RoleManager roleManager, - IOptions jwtSettings, - IDateTimeService dateTimeService, + private readonly RoleManager _roleManager; + private readonly SignInManager _signInManager; + private readonly UserManager _userManager; + + public AccountService(UserManager userManager, + RoleManager roleManager, + IOptions jwtSettings, + IDateTimeService dateTimeService, SignInManager signInManager, IEmailService emailService) { @@ -46,27 +43,19 @@ public AccountService(UserManager userManager, _jwtSettings = jwtSettings.Value; _dateTimeService = dateTimeService; _signInManager = signInManager; - this._emailService = emailService; + _emailService = emailService; } - public async Task> AuthenticateAsync(AuthenticationRequest request, string ipAddress) + public async Task> AuthenticateAsync(AuthenticationRequest request, + string ipAddress) { var user = await _userManager.FindByEmailAsync(request.Email); - if (user == null) - { - throw new ApiException($"No Accounts Registered with {request.Email}."); - } - var result = await _signInManager.PasswordSignInAsync(user.UserName, request.Password, false, lockoutOnFailure: false); - if (!result.Succeeded) - { - throw new ApiException($"Invalid Credentials for '{request.Email}'."); - } - if (!user.EmailConfirmed) - { - throw new ApiException($"Account Not Confirmed for '{request.Email}'."); - } - JwtSecurityToken jwtSecurityToken = await GenerateJWToken(user); - AuthenticationResponse response = new AuthenticationResponse(); + if (user == null) throw new ApiException($"No Accounts Registered with {request.Email}."); + var result = await _signInManager.PasswordSignInAsync(user.UserName, request.Password, false, false); + if (!result.Succeeded) throw new ApiException($"Invalid Credentials for '{request.Email}'."); + if (!user.EmailConfirmed) throw new ApiException($"Account Not Confirmed for '{request.Email}'."); + var jwtSecurityToken = await GenerateJWToken(user); + var response = new AuthenticationResponse(); response.Id = user.Id; response.JWToken = new JwtSecurityTokenHandler().WriteToken(jwtSecurityToken); response.Email = user.Email; @@ -83,9 +72,7 @@ public async Task> RegisterAsync(RegisterRequest request, strin { var userWithSameUserName = await _userManager.FindByNameAsync(request.UserName); if (userWithSameUserName != null) - { throw new ApiException($"Username '{request.UserName}' is already taken."); - } var user = new ApplicationUser { Email = request.Email, @@ -102,18 +89,60 @@ public async Task> RegisterAsync(RegisterRequest request, strin await _userManager.AddToRoleAsync(user, Roles.Basic.ToString()); var verificationUri = await SendVerificationEmail(user, origin); //TODO: Attach Email Service here and configure it via appsettings - await _emailService.SendAsync(new Application.DTOs.Email.EmailRequest() { From = "mail@codewithmukesh.com", To = user.Email, Body = $"Please confirm your account by visiting this URL {verificationUri}", Subject = "Confirm Registration" }); - return new Response(user.Id, message: $"User Registered. Please confirm your account by visiting this URL {verificationUri}"); - } - else - { - throw new ApiException($"{result.Errors}"); + await _emailService.SendAsync(new EmailRequest + { + From = "mail@codewithmukesh.com", To = user.Email, + Body = $"Please confirm your account by visiting this URL {verificationUri}", + Subject = "Confirm Registration" + }); + return new Response(user.Id, + $"User Registered. Please confirm your account by visiting this URL {verificationUri}"); } + + throw new ApiException($"{result.Errors}"); } - else + + throw new ApiException($"Email {request.Email} is already registered."); + } + + public async Task> ConfirmEmailAsync(string userId, string code) + { + var user = await _userManager.FindByIdAsync(userId); + code = Encoding.UTF8.GetString(WebEncoders.Base64UrlDecode(code)); + var result = await _userManager.ConfirmEmailAsync(user, code); + if (result.Succeeded) + return new Response(user.Id, + $"Account Confirmed for {user.Email}. You can now use the /api/Account/authenticate endpoint."); + throw new ApiException($"An error occured while confirming {user.Email}."); + } + + public async Task ForgotPassword(ForgotPasswordRequest model, string origin) + { + var account = await _userManager.FindByEmailAsync(model.Email); + + // always return ok response to prevent email enumeration + if (account == null) return; + + var code = await _userManager.GeneratePasswordResetTokenAsync(account); + var route = "api/account/reset-password/"; + var _enpointUri = new Uri(string.Concat($"{origin}/", route)); + var emailRequest = new EmailRequest { - throw new ApiException($"Email {request.Email } is already registered."); - } + Body = $"You reset token is - {code}", + To = model.Email, + Subject = "Reset Password" + }; + await _emailService.SendAsync(emailRequest); + } + + public async Task> ResetPassword(ResetPasswordRequest model) + { + var account = await _userManager.FindByEmailAsync(model.Email); + if (account == null) throw new ApiException($"No Accounts Registered with {model.Email}."); + var result = await _userManager.ResetPasswordAsync(account, model.Token, model.Password); + if (result.Succeeded) + return new Response(model.Email, "Password Resetted."); + throw new ApiException("Error occured while reseting the password."); } private async Task GenerateJWToken(ApplicationUser user) @@ -123,31 +152,28 @@ private async Task GenerateJWToken(ApplicationUser user) var roleClaims = new List(); - for (int i = 0; i < roles.Count; i++) - { - roleClaims.Add(new Claim("roles", roles[i])); - } + for (var i = 0; i < roles.Count; i++) roleClaims.Add(new Claim("roles", roles[i])); - string ipAddress = IpHelper.GetIpAddress(); + var ipAddress = IpHelper.GetIpAddress(); var claims = new[] - { - new Claim(JwtRegisteredClaimNames.Sub, user.UserName), - new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()), - new Claim(JwtRegisteredClaimNames.Email, user.Email), - new Claim("uid", user.Id), - new Claim("ip", ipAddress) - } - .Union(userClaims) - .Union(roleClaims); + { + new Claim(JwtRegisteredClaimNames.Sub, user.UserName), + new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()), + new Claim(JwtRegisteredClaimNames.Email, user.Email), + new Claim("uid", user.Id), + new Claim("ip", ipAddress) + } + .Union(userClaims) + .Union(roleClaims); var symmetricSecurityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtSettings.Key)); var signingCredentials = new SigningCredentials(symmetricSecurityKey, SecurityAlgorithms.HmacSha256); var jwtSecurityToken = new JwtSecurityToken( - issuer: _jwtSettings.Issuer, - audience: _jwtSettings.Audience, - claims: claims, + _jwtSettings.Issuer, + _jwtSettings.Audience, + claims, expires: DateTime.UtcNow.AddMinutes(_jwtSettings.DurationInMinutes), signingCredentials: signingCredentials); return jwtSecurityToken; @@ -161,7 +187,7 @@ private string RandomTokenString() // convert random bytes to hex string return BitConverter.ToString(randomBytes).Replace("-", ""); } - + private async Task SendVerificationEmail(ApplicationUser user, string origin) { var code = await _userManager.GenerateEmailConfirmationTokenAsync(user); @@ -174,24 +200,9 @@ private async Task SendVerificationEmail(ApplicationUser user, string or return verificationUri; } - public async Task> ConfirmEmailAsync(string userId, string code) - { - var user = await _userManager.FindByIdAsync(userId); - code = Encoding.UTF8.GetString(WebEncoders.Base64UrlDecode(code)); - var result = await _userManager.ConfirmEmailAsync(user, code); - if(result.Succeeded) - { - return new Response(user.Id, message: $"Account Confirmed for {user.Email}. You can now use the /api/Account/authenticate endpoint."); - } - else - { - throw new ApiException($"An error occured while confirming {user.Email}."); - } - } - private RefreshToken GenerateRefreshToken(string ipAddress) { - return new RefreshToken + return new() { Token = RandomTokenString(), Expires = DateTime.UtcNow.AddDays(7), @@ -199,40 +210,5 @@ private RefreshToken GenerateRefreshToken(string ipAddress) CreatedByIp = ipAddress }; } - - public async Task ForgotPassword(ForgotPasswordRequest model, string origin) - { - var account = await _userManager.FindByEmailAsync(model.Email); - - // always return ok response to prevent email enumeration - if (account == null) return; - - var code = await _userManager.GeneratePasswordResetTokenAsync(account); - var route = "api/account/reset-password/"; - var _enpointUri = new Uri(string.Concat($"{origin}/", route)); - var emailRequest = new EmailRequest() - { - Body = $"You reset token is - {code}", - To = model.Email, - Subject = "Reset Password", - }; - await _emailService.SendAsync(emailRequest); - } - - public async Task> ResetPassword(ResetPasswordRequest model) - { - var account = await _userManager.FindByEmailAsync(model.Email); - if (account == null) throw new ApiException($"No Accounts Registered with {model.Email}."); - var result = await _userManager.ResetPasswordAsync(account, model.Token, model.Password); - if(result.Succeeded) - { - return new Response(model.Email, message: $"Password Resetted."); - } - else - { - throw new ApiException($"Error occured while reseting the password."); - } - } } - -} +} \ No newline at end of file diff --git a/Infrastructure.Persistence/Contexts/ApplicationDbContext.cs b/Infrastructure.Persistence/Contexts/ApplicationDbContext.cs index 4128893..77ae8a4 100644 --- a/Infrastructure.Persistence/Contexts/ApplicationDbContext.cs +++ b/Infrastructure.Persistence/Contexts/ApplicationDbContext.cs @@ -1,34 +1,31 @@ -using Application.Interfaces; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Application.Interfaces; using Domain.Common; using Domain.Entities; using Microsoft.EntityFrameworkCore; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Text; -using System.Threading; -using System.Threading.Tasks; namespace Infrastructure.Persistence.Contexts { public class ApplicationDbContext : DbContext { - private readonly IDateTimeService _dateTime; private readonly IAuthenticatedUserService _authenticatedUser; + private readonly IDateTimeService _dateTime; - public ApplicationDbContext(DbContextOptions options, IDateTimeService dateTime, IAuthenticatedUserService authenticatedUser) : base(options) + public ApplicationDbContext(DbContextOptions options, IDateTimeService dateTime, + IAuthenticatedUserService authenticatedUser) : base(options) { ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking; _dateTime = dateTime; _authenticatedUser = authenticatedUser; } + public DbSet Products { get; set; } public override Task SaveChangesAsync(CancellationToken cancellationToken = new CancellationToken()) { foreach (var entry in ChangeTracker.Entries()) - { switch (entry.State) { case EntityState.Added: @@ -40,19 +37,18 @@ public ApplicationDbContext(DbContextOptions options, IDat entry.Entity.LastModifiedBy = _authenticatedUser.UserId; break; } - } + return base.SaveChangesAsync(cancellationToken); } + protected override void OnModelCreating(ModelBuilder builder) { //All Decimals will have 18,6 Range foreach (var property in builder.Model.GetEntityTypes() - .SelectMany(t => t.GetProperties()) - .Where(p => p.ClrType == typeof(decimal) || p.ClrType == typeof(decimal?))) - { + .SelectMany(t => t.GetProperties()) + .Where(p => p.ClrType == typeof(decimal) || p.ClrType == typeof(decimal?))) property.SetColumnType("decimal(18,6)"); - } base.OnModelCreating(builder); } } -} +} \ No newline at end of file diff --git a/Infrastructure.Persistence/Repositories/GenericRepositoryAsync.cs b/Infrastructure.Persistence/Repositories/GenericRepositoryAsync.cs index 91a459e..44d57e5 100644 --- a/Infrastructure.Persistence/Repositories/GenericRepositoryAsync.cs +++ b/Infrastructure.Persistence/Repositories/GenericRepositoryAsync.cs @@ -1,11 +1,9 @@ -using Application.Interfaces; -using Infrastructure.Persistence.Contexts; -using Microsoft.EntityFrameworkCore; -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; -using System.Text; using System.Threading.Tasks; +using Application.Interfaces; +using Infrastructure.Persistence.Contexts; +using Microsoft.EntityFrameworkCore; namespace Infrastructure.Persistence.Repository { @@ -55,8 +53,8 @@ public async Task DeleteAsync(T entity) public async Task> GetAllAsync() { return await _dbContext - .Set() - .ToListAsync(); + .Set() + .ToListAsync(); } } -} +} \ No newline at end of file diff --git a/Infrastructure.Persistence/Repositories/ProductRepositoryAsync.cs b/Infrastructure.Persistence/Repositories/ProductRepositoryAsync.cs index a6facaf..7b2a71f 100644 --- a/Infrastructure.Persistence/Repositories/ProductRepositoryAsync.cs +++ b/Infrastructure.Persistence/Repositories/ProductRepositoryAsync.cs @@ -1,11 +1,8 @@ -using Application.Interfaces.Repositories; +using System.Threading.Tasks; +using Application.Interfaces.Repositories; using Domain.Entities; using Infrastructure.Persistence.Contexts; using Infrastructure.Persistence.Repository; -using System; -using System.Collections.Generic; -using System.Text; -using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; namespace Infrastructure.Persistence.Repositories @@ -25,4 +22,4 @@ public Task IsUniqueBarcodeAsync(string barcode) .AllAsync(p => p.Barcode != barcode); } } -} +} \ No newline at end of file diff --git a/Infrastructure.Persistence/ServiceRegistration.cs b/Infrastructure.Persistence/ServiceRegistration.cs index c3419da..1d0473a 100644 --- a/Infrastructure.Persistence/ServiceRegistration.cs +++ b/Infrastructure.Persistence/ServiceRegistration.cs @@ -6,9 +6,6 @@ using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; -using System; -using System.Collections.Generic; -using System.Text; namespace Infrastructure.Persistence { @@ -17,21 +14,20 @@ public static class ServiceRegistration public static void AddPersistenceInfrastructure(this IServiceCollection services, IConfiguration configuration) { if (configuration.GetValue("UseInMemoryDatabase")) - { services.AddDbContext(options => options.UseInMemoryDatabase("ApplicationDb")); - } else - { services.AddDbContext(options => - options.UseSqlServer( - configuration.GetConnectionString("DefaultConnection"), - b => b.MigrationsAssembly(typeof(ApplicationDbContext).Assembly.FullName))); - } + options.UseSqlServer( + configuration.GetConnectionString("DefaultConnection"), + b => b.MigrationsAssembly(typeof(ApplicationDbContext).Assembly.FullName))); + #region Repositories + services.AddTransient(typeof(IGenericRepositoryAsync<>), typeof(GenericRepositoryAsync<>)); services.AddTransient(); + #endregion } } -} +} \ No newline at end of file diff --git a/Infrastructure.Shared/ServiceRegistration.cs b/Infrastructure.Shared/ServiceRegistration.cs index 6e84917..157119e 100644 --- a/Infrastructure.Shared/ServiceRegistration.cs +++ b/Infrastructure.Shared/ServiceRegistration.cs @@ -15,4 +15,4 @@ public static void AddSharedInfrastructure(this IServiceCollection services, ICo services.AddTransient(); } } -} +} \ No newline at end of file diff --git a/Infrastructure.Shared/Services/DateTimeService.cs b/Infrastructure.Shared/Services/DateTimeService.cs index c8be12b..835655d 100644 --- a/Infrastructure.Shared/Services/DateTimeService.cs +++ b/Infrastructure.Shared/Services/DateTimeService.cs @@ -1,8 +1,5 @@ -using Application.Interfaces; -using System; -using System.Collections.Generic; -using System.Reflection.Metadata.Ecma335; -using System.Text; +using System; +using Application.Interfaces; namespace Infrastructure.Shared.Services { @@ -10,4 +7,4 @@ public class DateTimeService : IDateTimeService { public DateTime NowUtc => DateTime.UtcNow; } -} +} \ No newline at end of file diff --git a/Infrastructure.Shared/Services/EmailService.cs b/Infrastructure.Shared/Services/EmailService.cs index ab47673..acfa48e 100644 --- a/Infrastructure.Shared/Services/EmailService.cs +++ b/Infrastructure.Shared/Services/EmailService.cs @@ -1,4 +1,6 @@ -using Application.DTOs.Email; +using System; +using System.Threading.Tasks; +using Application.DTOs.Email; using Application.Exceptions; using Application.Interfaces; using Domain.Settings; @@ -7,21 +9,20 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using MimeKit; -using System.Threading.Tasks; namespace Infrastructure.Shared.Services { public class EmailService : IEmailService { - public MailSettings _mailSettings { get; } - public ILogger _logger { get; } - - public EmailService(IOptions mailSettings,ILogger logger) + public EmailService(IOptions mailSettings, ILogger logger) { _mailSettings = mailSettings.Value; _logger = logger; } + public MailSettings _mailSettings { get; } + public ILogger _logger { get; } + public async Task SendAsync(EmailRequest request) { try @@ -39,13 +40,12 @@ public async Task SendAsync(EmailRequest request) smtp.Authenticate(_mailSettings.SmtpUser, _mailSettings.SmtpPass); await smtp.SendAsync(email); smtp.Disconnect(true); - } - catch (System.Exception ex) + catch (Exception ex) { _logger.LogError(ex.Message, ex); throw new ApiException(ex.Message); } } } -} +} \ No newline at end of file diff --git a/WebApi/CleanArchitecture.WebApi.xml b/WebApi/CleanArchitecture.WebApi.xml index 8dd32d6..4d83d0a 100644 --- a/WebApi/CleanArchitecture.WebApi.xml +++ b/WebApi/CleanArchitecture.WebApi.xml @@ -1,8 +1,9 @@ + - - WebApi - - - - + + WebApi + + + + \ No newline at end of file diff --git a/WebApi/Controllers/AccountController.cs b/WebApi/Controllers/AccountController.cs index cd1d01b..7146657 100644 --- a/WebApi/Controllers/AccountController.cs +++ b/WebApi/Controllers/AccountController.cs @@ -1,10 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; +using System.Threading.Tasks; using Application.DTOs.Account; using Application.Interfaces; -using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; namespace WebApi.Controllers @@ -14,45 +10,50 @@ namespace WebApi.Controllers public class AccountController : ControllerBase { private readonly IAccountService _accountService; + public AccountController(IAccountService accountService) { _accountService = accountService; } + [HttpPost("authenticate")] public async Task AuthenticateAsync(AuthenticationRequest request) { return Ok(await _accountService.AuthenticateAsync(request, GenerateIPAddress())); } + [HttpPost("register")] public async Task RegisterAsync(RegisterRequest request) { var origin = Request.Headers["origin"]; return Ok(await _accountService.RegisterAsync(request, origin)); } + [HttpGet("confirm-email")] - public async Task ConfirmEmailAsync([FromQuery]string userId, [FromQuery]string code) + public async Task ConfirmEmailAsync([FromQuery] string userId, [FromQuery] string code) { var origin = Request.Headers["origin"]; return Ok(await _accountService.ConfirmEmailAsync(userId, code)); } + [HttpPost("forgot-password")] public async Task ForgotPassword(ForgotPasswordRequest model) { await _accountService.ForgotPassword(model, Request.Headers["origin"]); return Ok(); } + [HttpPost("reset-password")] public async Task ResetPassword(ResetPasswordRequest model) { - return Ok(await _accountService.ResetPassword(model)); } + private string GenerateIPAddress() { if (Request.Headers.ContainsKey("X-Forwarded-For")) return Request.Headers["X-Forwarded-For"]; - else - return HttpContext.Connection.RemoteIpAddress.MapToIPv4().ToString(); + return HttpContext.Connection.RemoteIpAddress.MapToIPv4().ToString(); } } } \ No newline at end of file diff --git a/WebApi/Controllers/BaseApiController.cs b/WebApi/Controllers/BaseApiController.cs index 3c0bd6b..59c7fe5 100644 --- a/WebApi/Controllers/BaseApiController.cs +++ b/WebApi/Controllers/BaseApiController.cs @@ -2,7 +2,6 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.DependencyInjection; - namespace WebApi.Controllers { [ApiController] @@ -12,4 +11,4 @@ public abstract class BaseApiController : ControllerBase private IMediator _mediator; protected IMediator Mediator => _mediator ??= HttpContext.RequestServices.GetService(); } -} +} \ No newline at end of file diff --git a/WebApi/Controllers/MetaController.cs b/WebApi/Controllers/MetaController.cs index 52451d1..6cd8b6a 100644 --- a/WebApi/Controllers/MetaController.cs +++ b/WebApi/Controllers/MetaController.cs @@ -1,5 +1,5 @@ -using Microsoft.AspNetCore.Mvc; -using System.Diagnostics; +using System.Diagnostics; +using Microsoft.AspNetCore.Mvc; namespace WebApi.Controllers { @@ -16,4 +16,4 @@ public ActionResult Info() return Ok($"Version: {version}, Last Updated: {lastUpdate}"); } } -} +} \ No newline at end of file diff --git a/WebApi/Controllers/v1/ProductController.cs b/WebApi/Controllers/v1/ProductController.cs index 743a3db..f0818d8 100644 --- a/WebApi/Controllers/v1/ProductController.cs +++ b/WebApi/Controllers/v1/ProductController.cs @@ -1,14 +1,9 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Application.Features.Products.Commands; +using System.Threading.Tasks; using Application.Features.Products.Commands.CreateProduct; using Application.Features.Products.Commands.DeleteProductById; using Application.Features.Products.Commands.UpdateProduct; using Application.Features.Products.Queries.GetAllProducts; using Application.Features.Products.Queries.GetProductById; -using Application.Filters; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; @@ -23,15 +18,15 @@ public class ProductController : BaseApiController [HttpGet] public async Task Get([FromQuery] GetAllProductsParameter filter) { - - return Ok(await Mediator.Send(new GetAllProductsQuery() { PageSize = filter.PageSize, PageNumber = filter.PageNumber })); + return Ok(await Mediator.Send(new GetAllProductsQuery + {PageSize = filter.PageSize, PageNumber = filter.PageNumber})); } // GET api//5 [HttpGet("{id}")] public async Task Get(int id) { - return Ok(await Mediator.Send(new GetProductByIdQuery { Id = id })); + return Ok(await Mediator.Send(new GetProductByIdQuery {Id = id})); } // POST api/ @@ -47,10 +42,7 @@ public async Task Post(CreateProductCommand command) [Authorize] public async Task Put(int id, UpdateProductCommand command) { - if (id != command.Id) - { - return BadRequest(); - } + if (id != command.Id) return BadRequest(); return Ok(await Mediator.Send(command)); } @@ -59,7 +51,7 @@ public async Task Put(int id, UpdateProductCommand command) [Authorize] public async Task Delete(int id) { - return Ok(await Mediator.Send(new DeleteProductByIdCommand { Id = id })); + return Ok(await Mediator.Send(new DeleteProductByIdCommand {Id = id})); } } -} +} \ No newline at end of file diff --git a/WebApi/Extensions/AppExtensions.cs b/WebApi/Extensions/AppExtensions.cs index ec20d70..fe0bf82 100644 --- a/WebApi/Extensions/AppExtensions.cs +++ b/WebApi/Extensions/AppExtensions.cs @@ -1,8 +1,4 @@ using Microsoft.AspNetCore.Builder; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; using WebApi.Middlewares; namespace WebApi.Extensions @@ -12,14 +8,12 @@ public static class AppExtensions public static void UseSwaggerExtension(this IApplicationBuilder app) { app.UseSwagger(); - app.UseSwaggerUI(c => - { - c.SwaggerEndpoint("/swagger/v1/swagger.json", "CleanArchitecture.WebApi"); - }); + app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "CleanArchitecture.WebApi"); }); } + public static void UseErrorHandlingMiddleware(this IApplicationBuilder app) { app.UseMiddleware(); } } -} +} \ No newline at end of file diff --git a/WebApi/Extensions/ServiceExtensions.cs b/WebApi/Extensions/ServiceExtensions.cs index 183c7dd..fd281bc 100644 --- a/WebApi/Extensions/ServiceExtensions.cs +++ b/WebApi/Extensions/ServiceExtensions.cs @@ -1,10 +1,8 @@ -using Microsoft.AspNetCore.Mvc; +using System; +using System.Collections.Generic; +using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.DependencyInjection; using Microsoft.OpenApi.Models; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; namespace WebApi.Extensions { @@ -14,7 +12,8 @@ public static void AddSwaggerExtension(this IServiceCollection services) { services.AddSwaggerGen(c => { - c.IncludeXmlComments(string.Format(@"{0}\CleanArchitecture.WebApi.xml", System.AppDomain.CurrentDomain.BaseDirectory)); + c.IncludeXmlComments(string.Format(@"{0}\CleanArchitecture.WebApi.xml", + AppDomain.CurrentDomain.BaseDirectory)); c.SwaggerDoc("v1", new OpenApiInfo { Version = "v1", @@ -24,7 +23,7 @@ public static void AddSwaggerExtension(this IServiceCollection services) { Name = "codewithmukesh", Email = "hello@codewithmukesh.com", - Url = new Uri("https://codewithmukesh.com/contact"), + Url = new Uri("https://codewithmukesh.com/contact") } }); c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme @@ -34,7 +33,7 @@ public static void AddSwaggerExtension(this IServiceCollection services) Type = SecuritySchemeType.ApiKey, Scheme = "Bearer", BearerFormat = "JWT", - Description = "Input your Bearer token in this format - Bearer {your token here} to access this API", + Description = "Input your Bearer token in this format - Bearer {your token here} to access this API" }); c.AddSecurityRequirement(new OpenApiSecurityRequirement { @@ -44,16 +43,18 @@ public static void AddSwaggerExtension(this IServiceCollection services) Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, - Id = "Bearer", + Id = "Bearer" }, Scheme = "Bearer", Name = "Bearer", - In = ParameterLocation.Header, - }, new List() - }, + In = ParameterLocation.Header + }, + new List() + } }); }); } + public static void AddApiVersioningExtension(this IServiceCollection services) { services.AddApiVersioning(config => @@ -67,4 +68,4 @@ public static void AddApiVersioningExtension(this IServiceCollection services) }); } } -} +} \ No newline at end of file diff --git a/WebApi/Middlewares/ErrorHandlerMiddleware.cs b/WebApi/Middlewares/ErrorHandlerMiddleware.cs index b04aec5..f7bcb84 100644 --- a/WebApi/Middlewares/ErrorHandlerMiddleware.cs +++ b/WebApi/Middlewares/ErrorHandlerMiddleware.cs @@ -1,12 +1,11 @@ -using Application.Exceptions; -using Application.Wrappers; -using Microsoft.AspNetCore.Http; -using System; +using System; using System.Collections.Generic; -using System.Linq; using System.Net; using System.Text.Json; using System.Threading.Tasks; +using Application.Exceptions; +using Application.Wrappers; +using Microsoft.AspNetCore.Http; namespace WebApi.Middlewares { @@ -29,32 +28,33 @@ public async Task Invoke(HttpContext context) { var response = context.Response; response.ContentType = "application/json"; - var responseModel = new Response() { Succeeded = false, Message = error?.Message }; - + var responseModel = new Response {Succeeded = false, Message = error?.Message}; + switch (error) { - case Application.Exceptions.ApiException e: + case ApiException e: // custom application error - response.StatusCode = (int)HttpStatusCode.BadRequest; + response.StatusCode = (int) HttpStatusCode.BadRequest; break; case ValidationException e: // custom application error - response.StatusCode = (int)HttpStatusCode.BadRequest; + response.StatusCode = (int) HttpStatusCode.BadRequest; responseModel.Errors = e.Errors; break; case KeyNotFoundException e: // not found error - response.StatusCode = (int)HttpStatusCode.NotFound; + response.StatusCode = (int) HttpStatusCode.NotFound; break; default: // unhandled error - response.StatusCode = (int)HttpStatusCode.InternalServerError; + response.StatusCode = (int) HttpStatusCode.InternalServerError; break; } + var result = JsonSerializer.Serialize(responseModel); await response.WriteAsync(result); } } } -} +} \ No newline at end of file diff --git a/WebApi/Models/Metadata.cs b/WebApi/Models/Metadata.cs index 10640d8..4c4599e 100644 --- a/WebApi/Models/Metadata.cs +++ b/WebApi/Models/Metadata.cs @@ -1,11 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace WebApi.Models +namespace WebApi.Models { public class Metadata { } -} +} \ No newline at end of file diff --git a/WebApi/Program.cs b/WebApi/Program.cs index aeefde8..4c55fd7 100644 --- a/WebApi/Program.cs +++ b/WebApi/Program.cs @@ -1,24 +1,20 @@ using System; -using System.Collections.Generic; -using System.Linq; using System.Threading.Tasks; +using Infrastructure.Identity.Models; +using Infrastructure.Identity.Seeds; using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; -using Microsoft.AspNetCore.Http.Extensions; using Serilog; -using Infrastructure.Identity; -using Microsoft.AspNetCore.Identity; -using Infrastructure.Identity.Models; -using Microsoft.Extensions.DependencyInjection; namespace WebApi { public class Program { - public async static Task Main(string[] args) + public static async Task Main(string[] args) { //Read Configuration from appSettings var config = new ConfigurationBuilder() @@ -39,9 +35,9 @@ public async static Task Main(string[] args) var userManager = services.GetRequiredService>(); var roleManager = services.GetRequiredService>(); - await Infrastructure.Identity.Seeds.DefaultRoles.SeedAsync(userManager, roleManager); - await Infrastructure.Identity.Seeds.DefaultSuperAdmin.SeedAsync(userManager, roleManager); - await Infrastructure.Identity.Seeds.DefaultBasicUser.SeedAsync(userManager, roleManager); + await DefaultRoles.SeedAsync(userManager, roleManager); + await DefaultSuperAdmin.SeedAsync(userManager, roleManager); + await DefaultBasicUser.SeedAsync(userManager, roleManager); Log.Information("Finished Seeding Default Data"); Log.Information("Application Starting"); } @@ -54,14 +50,15 @@ public async static Task Main(string[] args) Log.CloseAndFlush(); } } + host.Run(); } - public static IHostBuilder CreateHostBuilder(string[] args) => - Host.CreateDefaultBuilder(args) - .UseSerilog() //Uses Serilog instead of default .NET Logger - .ConfigureWebHostDefaults(webBuilder => - { - webBuilder.UseStartup(); - }); + + public static IHostBuilder CreateHostBuilder(string[] args) + { + return Host.CreateDefaultBuilder(args) + .UseSerilog() //Uses Serilog instead of default .NET Logger + .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup(); }); + } } -} +} \ No newline at end of file diff --git a/WebApi/Properties/launchSettings.json b/WebApi/Properties/launchSettings.json index 363ac1d..52863c0 100644 --- a/WebApi/Properties/launchSettings.json +++ b/WebApi/Properties/launchSettings.json @@ -27,4 +27,4 @@ } } } -} +} \ No newline at end of file diff --git a/WebApi/Services/AuthenticatedUserService.cs b/WebApi/Services/AuthenticatedUserService.cs index d36d0f6..e86c25a 100644 --- a/WebApi/Services/AuthenticatedUserService.cs +++ b/WebApi/Services/AuthenticatedUserService.cs @@ -1,10 +1,6 @@ -using Application.Interfaces; +using System.Security.Claims; +using Application.Interfaces; using Microsoft.AspNetCore.Http; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Security.Claims; -using System.Threading.Tasks; namespace WebApi.Services { @@ -17,4 +13,4 @@ public AuthenticatedUserService(IHttpContextAccessor httpContextAccessor) public string UserId { get; } } -} +} \ No newline at end of file diff --git a/WebApi/Startup.cs b/WebApi/Startup.cs index bf76c2e..d8c54b3 100644 --- a/WebApi/Startup.cs +++ b/WebApi/Startup.cs @@ -15,11 +15,13 @@ namespace WebApi { public class Startup { - public IConfiguration _config { get; } public Startup(IConfiguration configuration) { _config = configuration; } + + public IConfiguration _config { get; } + public void ConfigureServices(IServiceCollection services) { services.AddApplicationLayer(); @@ -44,6 +46,7 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env) app.UseExceptionHandler("/Error"); app.UseHsts(); } + app.UseHttpsRedirection(); app.UseRouting(); app.UseAuthentication(); @@ -52,10 +55,7 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env) app.UseErrorHandlingMiddleware(); app.UseHealthChecks("/health"); - app.UseEndpoints(endpoints => - { - endpoints.MapControllers(); - }); + app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } } -} +} \ No newline at end of file diff --git a/WebApi/appsettings.json b/WebApi/appsettings.json index c71d85e..3bab2b1 100644 --- a/WebApi/appsettings.json +++ b/WebApi/appsettings.json @@ -1,8 +1,10 @@ { "UseInMemoryDatabase": false, "ConnectionStrings": { - "DefaultConnection": "Data Source=DESKTOP-QCM5AL0;Initial Catalog=CleanArchitectureApplicationDb;Integrated Security=True;MultipleActiveResultSets=True", - "IdentityConnection": "Data Source=DESKTOP-QCM5AL0;Initial Catalog=identityDb;Integrated Security=True;MultipleActiveResultSets=True" + "DefaultConnection": + "Data Source=DESKTOP-QCM5AL0;Initial Catalog=CleanArchitectureApplicationDb;Integrated Security=True;MultipleActiveResultSets=True", + "IdentityConnection": + "Data Source=DESKTOP-QCM5AL0;Initial Catalog=identityDb;Integrated Security=True;MultipleActiveResultSets=True" }, "Serilog": { "Using": [], @@ -43,4 +45,4 @@ "DurationInMinutes": 60 }, "AllowedHosts": "*" -} +} \ No newline at end of file From a10f2a282375566d2707db672a470d1fb8f7e6cd Mon Sep 17 00:00:00 2001 From: "M.F.M Fazrin" Date: Fri, 2 Jul 2021 15:11:46 +0530 Subject: [PATCH 2/2] Commit the changes --- Application/DTOs/Account/AuthenticationResponse.cs | 1 - Infrastructure.Identity/ServiceExtensions.cs | 1 + .../Migrations/ApplicationDbContextModelSnapshot.cs | 1 - WebApi/CleanArchitecture.WebApi.xml | 13 ++++++------- WebApi/appsettings.json | 6 ++---- 5 files changed, 9 insertions(+), 13 deletions(-) diff --git a/Application/DTOs/Account/AuthenticationResponse.cs b/Application/DTOs/Account/AuthenticationResponse.cs index 6daf03e..6658097 100644 --- a/Application/DTOs/Account/AuthenticationResponse.cs +++ b/Application/DTOs/Account/AuthenticationResponse.cs @@ -11,7 +11,6 @@ public class AuthenticationResponse public List Roles { get; set; } public bool IsVerified { get; set; } public string JWToken { get; set; } - [JsonIgnore] public string RefreshToken { get; set; } } } \ No newline at end of file diff --git a/Infrastructure.Identity/ServiceExtensions.cs b/Infrastructure.Identity/ServiceExtensions.cs index 3593538..a029367 100644 --- a/Infrastructure.Identity/ServiceExtensions.cs +++ b/Infrastructure.Identity/ServiceExtensions.cs @@ -29,6 +29,7 @@ public static void AddIdentityInfrastructure(this IServiceCollection services, I options.UseSqlServer( configuration.GetConnectionString("IdentityConnection"), b => b.MigrationsAssembly(typeof(IdentityContext).Assembly.FullName))); + services.AddIdentity().AddEntityFrameworkStores() .AddDefaultTokenProviders(); diff --git a/Infrastructure.Persistence/Migrations/ApplicationDbContextModelSnapshot.cs b/Infrastructure.Persistence/Migrations/ApplicationDbContextModelSnapshot.cs index fd81090..d7fd834 100644 --- a/Infrastructure.Persistence/Migrations/ApplicationDbContextModelSnapshot.cs +++ b/Infrastructure.Persistence/Migrations/ApplicationDbContextModelSnapshot.cs @@ -4,7 +4,6 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; namespace Infrastructure.Persistence.Migrations { diff --git a/WebApi/CleanArchitecture.WebApi.xml b/WebApi/CleanArchitecture.WebApi.xml index 4d83d0a..8dd32d6 100644 --- a/WebApi/CleanArchitecture.WebApi.xml +++ b/WebApi/CleanArchitecture.WebApi.xml @@ -1,9 +1,8 @@ - - - WebApi - - - - \ No newline at end of file + + WebApi + + + + diff --git a/WebApi/appsettings.json b/WebApi/appsettings.json index 3bab2b1..77b6139 100644 --- a/WebApi/appsettings.json +++ b/WebApi/appsettings.json @@ -1,10 +1,8 @@ { "UseInMemoryDatabase": false, "ConnectionStrings": { - "DefaultConnection": - "Data Source=DESKTOP-QCM5AL0;Initial Catalog=CleanArchitectureApplicationDb;Integrated Security=True;MultipleActiveResultSets=True", - "IdentityConnection": - "Data Source=DESKTOP-QCM5AL0;Initial Catalog=identityDb;Integrated Security=True;MultipleActiveResultSets=True" + "DefaultConnection": "Data Source=DESKTOP-02RK9HN\\QUADRATESQL;Initial Catalog=CleanArchitectureApplicationDb;Integrated Security=True;MultipleActiveResultSets=True", + "IdentityConnection": "Data Source=DESKTOP-02RK9HN\\QUADRATESQL;Initial Catalog=identityDb;Integrated Security=True;MultipleActiveResultSets=True" }, "Serilog": { "Using": [],