| [*.cs] | |||||
| # CS8618: Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. | |||||
| dotnet_diagnostic.CS8618.severity = none |
| ################################################################################ | |||||
| # This .gitignore file was automatically created by Microsoft(R) Visual Studio. | |||||
| ################################################################################ | |||||
| /.vs | |||||
| /Diligent.WebAPI.Data/bin/Debug/net6.0 | |||||
| /Diligent.WebAPI.Data/obj | |||||
| /Diligent.WebAPI.Host/.vs/Diligent.WebAPI/v17 | |||||
| /Diligent.WebAPI.Host/bin/Debug/net6.0 | |||||
| /Diligent.WebAPI.Host/obj | |||||
| /Diligent.WebAPI.Host/Logs | |||||
| /Diligent.WebAPI.Business/bin/Debug/net6.0 | |||||
| /Diligent.WebAPI.Business/obj/Debug/net6.0 | |||||
| /Diligent.WebAPI.Business/obj | |||||
| /Diligent.WebAPI.Contracts/bin/Debug/net6.0 | |||||
| /Diligent.WebAPI.Contracts/obj/Debug/net6.0 | |||||
| /Diligent.WebAPI.Contracts/obj |
| <Project Sdk="Microsoft.NET.Sdk"> | |||||
| <PropertyGroup> | |||||
| <TargetFramework>net6.0</TargetFramework> | |||||
| <ImplicitUsings>enable</ImplicitUsings> | |||||
| <Nullable>enable</Nullable> | |||||
| </PropertyGroup> | |||||
| <ItemGroup> | |||||
| <PackageReference Include="AutoMapper" Version="11.0.1" /> | |||||
| <PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="11.0.0" /> | |||||
| <PackageReference Include="RestSharp" Version="108.0.2-alpha.0.6" /> | |||||
| </ItemGroup> | |||||
| <ItemGroup> | |||||
| <ProjectReference Include="..\Diligent.WebAPI.Contracts\Diligent.WebAPI.Contracts.csproj" /> | |||||
| <ProjectReference Include="..\Diligent.WebAPI.Data\Diligent.WebAPI.Data.csproj" /> | |||||
| </ItemGroup> | |||||
| </Project> |
| namespace Diligent.WebAPI.Business.MappingProfiles | |||||
| { | |||||
| public class CompanyMappingProfile : Profile | |||||
| { | |||||
| public CompanyMappingProfile() | |||||
| { | |||||
| #region Models to DTOs | |||||
| CreateMap<InsuranceCompany, InsuranceCompanyViewDto>(); | |||||
| #endregion | |||||
| #region DTOs to Models | |||||
| CreateMap<InsuranceCompanyCreateDto, InsuranceCompany>(); | |||||
| CreateMap<InsuranceCompanyUpdateDto, InsuranceCompany>(); | |||||
| #endregion | |||||
| } | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Business.MappingProfiles | |||||
| { | |||||
| public class InsurerMappingProfile : Profile | |||||
| { | |||||
| public InsurerMappingProfile() | |||||
| { | |||||
| #region DTO to Model | |||||
| CreateMap<InsurerCreateDto, Insurer>(); | |||||
| CreateMap<InsurerUpdateDto, Insurer>(); | |||||
| #endregion | |||||
| #region Model to DTO | |||||
| CreateMap<Insurer, InsurerViewDto>(); | |||||
| #endregion | |||||
| } | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Business.MappingProfiles | |||||
| { | |||||
| public class PolicyMappingProfiles : Profile | |||||
| { | |||||
| public PolicyMappingProfiles() | |||||
| { | |||||
| CreateMap<InsurancePolicy, InsurancePolicyViewDto>(); | |||||
| CreateMap<InsurancePolicyCreateDto, InsurancePolicy>(); | |||||
| CreateMap<InsurancePolicyUpdateDto, InsurancePolicy>(); | |||||
| } | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Business.MappingProfiles | |||||
| { | |||||
| public class WebhookMappingProfile : Profile | |||||
| { | |||||
| public WebhookMappingProfile() | |||||
| { | |||||
| #region DTO to Model | |||||
| CreateMap<WebhookSubscriptionCreateDto, WebhookSubscription>(); | |||||
| #endregion | |||||
| #region Model to DTO | |||||
| CreateMap<WebhookDefinition, WebhookDefinitionViewDto>(); | |||||
| #endregion | |||||
| } | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Business.Services | |||||
| { | |||||
| public class InsuranceCompaniesService : IInsuranceCompaniesService | |||||
| { | |||||
| private readonly DatabaseContext _context; | |||||
| private readonly IMapper _mapper; | |||||
| public InsuranceCompaniesService(DatabaseContext context, IMapper mapper) | |||||
| { | |||||
| _context = context; | |||||
| _mapper = mapper; | |||||
| } | |||||
| public async Task<List<InsuranceCompanyViewDto>> GetInsuranceCompanies() | |||||
| { | |||||
| var insuranceCompanies = await _context.InsuranceCompanies.ToListAsync(); | |||||
| var insuranceCompaniesDto = _mapper.Map<List<InsuranceCompanyViewDto>>(insuranceCompanies); | |||||
| return insuranceCompaniesDto; | |||||
| } | |||||
| public async Task<InsuranceCompanyViewDto?> GetInsuranceCompany(long id) | |||||
| { | |||||
| var insuranceCompany = await _context.InsuranceCompanies.FindAsync(id); | |||||
| if (insuranceCompany == null) | |||||
| throw new EntityNotFoundException("Insurance company not found"); | |||||
| var insuranceCompanyDto = _mapper.Map<InsuranceCompanyViewDto?>(insuranceCompany); | |||||
| return insuranceCompanyDto; | |||||
| } | |||||
| public async Task CreateInsuranceCompany(InsuranceCompanyCreateDto insuranceCompanyCreateDto) | |||||
| { | |||||
| var insuranceCompany = _mapper.Map<InsuranceCompany>(insuranceCompanyCreateDto); | |||||
| insuranceCompany.CreatedAtUtc = DateTime.UtcNow; | |||||
| await _context.InsuranceCompanies.AddAsync(insuranceCompany); | |||||
| await _context.SaveChangesAsync(); | |||||
| } | |||||
| public async Task UpdateInsuranceCompany(long insuranceCompanyId, InsuranceCompanyUpdateDto insuranceCompanyUpdateDto) | |||||
| { | |||||
| var insuranceCompany = _context.InsuranceCompanies.Find(insuranceCompanyId); | |||||
| if (insuranceCompany == null) | |||||
| throw new EntityNotFoundException($"Insurance company not found"); | |||||
| _mapper.Map(insuranceCompanyUpdateDto, insuranceCompany); | |||||
| insuranceCompany.UpdatedAtUtc = DateTime.UtcNow; | |||||
| _context.Entry(insuranceCompany).State = EntityState.Modified; | |||||
| await _context.SaveChangesAsync(); | |||||
| } | |||||
| public async Task DeleteInsuranceCompany(long insuranceCompanyId) | |||||
| { | |||||
| var insuranceCompany = _context.InsuranceCompanies.Find(insuranceCompanyId); | |||||
| if (insuranceCompany == null) | |||||
| throw new EntityNotFoundException("Insurance company not found"); | |||||
| _context.Remove(insuranceCompany); | |||||
| await _context.SaveChangesAsync(); | |||||
| } | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Business.Services | |||||
| { | |||||
| public class InsurancePoliciesService : IInsurancePoliciesService | |||||
| { | |||||
| private readonly DatabaseContext _context; | |||||
| private readonly IWebhookPublisherService _webhookPublisher; | |||||
| private readonly IMapper _mapper; | |||||
| public InsurancePoliciesService(DatabaseContext context, IWebhookPublisherService webhookPublisher, IMapper mapper) | |||||
| { | |||||
| _context = context; | |||||
| _webhookPublisher = webhookPublisher; | |||||
| _mapper = mapper; | |||||
| } | |||||
| public async Task<List<InsurancePolicyViewDto>> GetInsurancePolicies() | |||||
| { | |||||
| var insurancePolicies = await _context.InsurancePolicies | |||||
| .Include(i => i.Insurer) | |||||
| .ThenInclude(k => k.InsuranceCompany) | |||||
| .ToListAsync(); | |||||
| var insurancePoliciesDto = _mapper.Map<List<InsurancePolicyViewDto>>(insurancePolicies); | |||||
| return insurancePoliciesDto; | |||||
| } | |||||
| public async Task<InsurancePolicyViewDto?> GetInsurancePolicy(long id) | |||||
| { | |||||
| var insurancePolicy = await _context.InsurancePolicies | |||||
| .Include(i => i.Insurer) | |||||
| .ThenInclude(k => k.InsuranceCompany) | |||||
| .FirstOrDefaultAsync(i => i.Id == id); | |||||
| if (insurancePolicy == null) | |||||
| throw new EntityNotFoundException("Insurance policy not found"); | |||||
| var insurancePolicyDto = _mapper.Map<InsurancePolicyViewDto>(insurancePolicy); | |||||
| return insurancePolicyDto; | |||||
| } | |||||
| public async Task CreateInsurancePolicy(InsurancePolicyCreateDto insurancePolicyCreateDto) | |||||
| { | |||||
| var insurancePolicy = _mapper.Map<InsurancePolicy>(insurancePolicyCreateDto); | |||||
| var result = await _context.InsurancePolicies.AddAsync(insurancePolicy); | |||||
| await _webhookPublisher.PublishAsync("insurancePolicy.created", result); | |||||
| await _context.SaveChangesAsync(); | |||||
| } | |||||
| public async Task UpdateInsurancePolicy(long insurancePolicyId, InsurancePolicyUpdateDto insurancePolicyUpdateDto) | |||||
| { | |||||
| var insurancePolicy = _context.InsurancePolicies.Find(insurancePolicyId); | |||||
| if (insurancePolicy == null) | |||||
| throw new EntityNotFoundException("Insurance policy not found"); | |||||
| _mapper.Map(insurancePolicyUpdateDto, insurancePolicy); | |||||
| insurancePolicy.UpdatedAtUtc = DateTime.UtcNow; | |||||
| _context.Entry(insurancePolicy).State = EntityState.Modified; | |||||
| await _context.SaveChangesAsync(); | |||||
| } | |||||
| public async Task DeleteInsurancePolicy(long insurancePolicyId) | |||||
| { | |||||
| var insurancePolicy = _context.InsurancePolicies.Find(insurancePolicyId); | |||||
| if (insurancePolicy == null) | |||||
| throw new EntityNotFoundException("Insurance policy not found"); | |||||
| _context.Remove(insurancePolicy); | |||||
| await _context.SaveChangesAsync(); | |||||
| } | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Business.Services | |||||
| { | |||||
| public class InsurersService : IInsurersService | |||||
| { | |||||
| private readonly DatabaseContext _context; | |||||
| private readonly IMapper _mapper; | |||||
| public InsurersService(DatabaseContext context, IMapper mapper) | |||||
| { | |||||
| _context = context; | |||||
| _mapper = mapper; | |||||
| } | |||||
| public async Task<List<InsurerViewDto>> GetInsurers() | |||||
| { | |||||
| var insurers = await _context.Insurers.Include(x => x.InsuranceCompany).ToListAsync(); | |||||
| return _mapper.Map<List<InsurerViewDto>>(insurers); | |||||
| } | |||||
| public async Task<InsurerViewDto?> GetInsurer(long id) | |||||
| { | |||||
| var insurer = await _context.Insurers | |||||
| .Include(x => x.InsuranceCompany) | |||||
| .FirstOrDefaultAsync(x => x.Id == id); | |||||
| if (insurer == null) | |||||
| throw new EntityNotFoundException("Insurer not found"); | |||||
| return _mapper.Map<InsurerViewDto>(insurer); | |||||
| } | |||||
| public async Task CreateInsurer(InsurerCreateDto insurerCreateDto) | |||||
| { | |||||
| var insurer = _mapper.Map<Insurer>(insurerCreateDto); | |||||
| await _context.Insurers.AddAsync(insurer); | |||||
| await _context.SaveChangesAsync(); | |||||
| } | |||||
| public async Task UpdateInsurer(long insurerId, InsurerUpdateDto insurerUpdateDto) | |||||
| { | |||||
| var insurer = _context.InsurancePolicies.Find(insurerId); | |||||
| if (insurer == null) | |||||
| throw new EntityNotFoundException("Insurer not found"); | |||||
| _mapper.Map(insurerUpdateDto, insurer); | |||||
| insurer.UpdatedAtUtc = DateTime.UtcNow; | |||||
| _context.Entry(insurer).State = EntityState.Modified; | |||||
| await _context.SaveChangesAsync(); | |||||
| } | |||||
| public async Task DeleteInsurerAsync(long insurerId) | |||||
| { | |||||
| var insurer = _context.InsurancePolicies.Find(insurerId); | |||||
| if (insurer == null) | |||||
| throw new EntityNotFoundException("Insurer not found"); | |||||
| _context.Remove(insurer); | |||||
| await _context.SaveChangesAsync(); | |||||
| } | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Business.Services.Interfaces | |||||
| { | |||||
| public interface IInsuranceCompaniesService | |||||
| { | |||||
| Task<List<InsuranceCompanyViewDto>> GetInsuranceCompanies(); | |||||
| Task<InsuranceCompanyViewDto?> GetInsuranceCompany(long id); | |||||
| Task CreateInsuranceCompany(InsuranceCompanyCreateDto insuranceCompanyCreateDto); | |||||
| Task UpdateInsuranceCompany(long insuranceCompanyId, InsuranceCompanyUpdateDto insuranceCompanyUpdateDto); | |||||
| Task DeleteInsuranceCompany(long insuranceCompanyId); | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Business.Services.Interfaces | |||||
| { | |||||
| public interface IInsurancePoliciesService | |||||
| { | |||||
| Task<List<InsurancePolicyViewDto>> GetInsurancePolicies(); | |||||
| Task<InsurancePolicyViewDto?> GetInsurancePolicy(long id); | |||||
| Task CreateInsurancePolicy(InsurancePolicyCreateDto insurancePolicyCreateDto); | |||||
| Task UpdateInsurancePolicy(long insurancePolicyId, InsurancePolicyUpdateDto insurancePolicyUpdateDto); | |||||
| Task DeleteInsurancePolicy(long insurancePolicyId); | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Business.Services.Interfaces | |||||
| { | |||||
| public interface IInsurersService | |||||
| { | |||||
| Task<List<InsurerViewDto>> GetInsurers(); | |||||
| Task<InsurerViewDto?> GetInsurer(long id); | |||||
| Task CreateInsurer(InsurerCreateDto insurerCreateDto); | |||||
| Task UpdateInsurer(long insurerId, InsurerUpdateDto insurerUpdateDto); | |||||
| Task DeleteInsurerAsync(long insurerId); | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Business.Services.Interfaces | |||||
| { | |||||
| public interface IUserService | |||||
| { | |||||
| AuthenticateResponseDto? Authenticate(AuthenticateRequestDto model); | |||||
| IEnumerable<User?> GetAll(); | |||||
| User? GetById(int id); | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Business.Services.Interfaces | |||||
| { | |||||
| public interface IWebhookDefinitionService | |||||
| { | |||||
| /// <summary> | |||||
| /// Get all webhook definitions | |||||
| /// </summary> | |||||
| Task<List<WebhookDefinitionViewDto>> GetAll(); | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Business.Services.Interfaces | |||||
| { | |||||
| public interface IWebhookPublisherService | |||||
| { | |||||
| Task PublishAsync(string webhookName, object data); | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Business.Services.Interfaces | |||||
| { | |||||
| public interface IWebhookSubscriptionService | |||||
| { | |||||
| /// <summary> | |||||
| /// Create new webhook subscription | |||||
| /// </summary> | |||||
| Task<WebhookSubscription> CreateWebhookSubscription(WebhookSubscriptionCreateDto dto); | |||||
| /// <summary> | |||||
| /// Get subscriptions by webhook name | |||||
| /// </summary> | |||||
| Task<List<WebhookSubscription>> GetAllSubscriptionsAsync(string webhookName); | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Business.Services | |||||
| { | |||||
| public class UserService : IUserService | |||||
| { | |||||
| private readonly AuthorizationSettings _authSettings; | |||||
| public UserService(IOptions<AuthorizationSettings> authSettings) | |||||
| { | |||||
| _authSettings = authSettings.Value; | |||||
| } | |||||
| // User list for testing | |||||
| private readonly List<User> _users = new List<User> | |||||
| { | |||||
| new User { Id = 1, FirstName = "Test", LastName = "User", Username = "test", Password = "test" } | |||||
| }; | |||||
| public AuthenticateResponseDto? Authenticate(AuthenticateRequestDto model) | |||||
| { | |||||
| var user = _users.SingleOrDefault(x => x.Username == model.Username && x.Password == model.Password); | |||||
| // return null if user not found | |||||
| if (user == null) | |||||
| return null; | |||||
| // authentication successful so generate jwt token | |||||
| var token = GenerateJwtToken(user); | |||||
| return new AuthenticateResponseDto | |||||
| { | |||||
| Id = user.Id, | |||||
| Username = user.Username, | |||||
| FirstName = user.FirstName, | |||||
| LastName = user.LastName, | |||||
| Token = token | |||||
| }; | |||||
| } | |||||
| public IEnumerable<User> GetAll() | |||||
| { | |||||
| return _users; | |||||
| } | |||||
| public User? GetById(int id) | |||||
| { | |||||
| return _users.FirstOrDefault(x => x.Id == id); | |||||
| } | |||||
| private string GenerateJwtToken(User user) | |||||
| { | |||||
| // generate token that is valid for 7 days | |||||
| var tokenHandler = new JwtSecurityTokenHandler(); | |||||
| var key = Encoding.ASCII.GetBytes(_authSettings.Secret); | |||||
| var tokenDescriptor = new SecurityTokenDescriptor | |||||
| { | |||||
| Subject = new ClaimsIdentity(new[] { new Claim("id", user.Id.ToString()) }), | |||||
| Expires = DateTime.UtcNow.AddMinutes(2), | |||||
| SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature) | |||||
| }; | |||||
| var token = tokenHandler.CreateToken(tokenDescriptor); | |||||
| return tokenHandler.WriteToken(token); | |||||
| } | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Business.Services | |||||
| { | |||||
| public class WebhookDefinitionService : IWebhookDefinitionService | |||||
| { | |||||
| private readonly DatabaseContext _context; | |||||
| private readonly IMapper _mapper; | |||||
| public WebhookDefinitionService(DatabaseContext context, IMapper mapper) | |||||
| { | |||||
| _context = context; | |||||
| _mapper = mapper; | |||||
| } | |||||
| public async Task<List<WebhookDefinitionViewDto>> GetAll() | |||||
| { | |||||
| var webhookDefinitions = await _context.WebhookDefinitions.ToListAsync(); | |||||
| return _mapper.Map<List<WebhookDefinitionViewDto>>(webhookDefinitions); | |||||
| } | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Business.Services | |||||
| { | |||||
| public class WebhookPublisherService : IWebhookPublisherService | |||||
| { | |||||
| private readonly IWebhookSubscriptionService _subscriptionService; | |||||
| public WebhookPublisherService(IWebhookSubscriptionService subscriptionService) | |||||
| { | |||||
| _subscriptionService = subscriptionService; | |||||
| } | |||||
| public async Task PublishAsync(string webhookName, object data) | |||||
| { | |||||
| // Get all subscriptions | |||||
| var subscriptions = await _subscriptionService.GetAllSubscriptionsAsync(webhookName); | |||||
| if (subscriptions == null || subscriptions.Count == 0) | |||||
| return; | |||||
| // Send POST request to subscriptions | |||||
| // 1: define POST request | |||||
| var request = new RestRequest("", Method.Post); | |||||
| // 2: define request body | |||||
| var serializedOrder = JsonConvert.SerializeObject(data, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); | |||||
| request.AddJsonBody(serializedOrder); | |||||
| // 3: define request headers | |||||
| request.AddHeader("Content-Type", "application/json"); | |||||
| foreach (var subscription in subscriptions) | |||||
| { | |||||
| try | |||||
| { | |||||
| // 4: define client endpoint | |||||
| var client = new RestClient(subscription.WebhookURL); | |||||
| // 5: send | |||||
| await client.ExecuteAsync(request); | |||||
| } | |||||
| catch (Exception) | |||||
| { | |||||
| // if one subscription fail continue | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Business.Services | |||||
| { | |||||
| public class WebhookSubscriptionService : IWebhookSubscriptionService | |||||
| { | |||||
| private readonly DatabaseContext _context; | |||||
| private readonly IMapper _mapper; | |||||
| public WebhookSubscriptionService(DatabaseContext context, IMapper mapper) | |||||
| { | |||||
| _context = context; | |||||
| _mapper = mapper; | |||||
| } | |||||
| public async Task<WebhookSubscription> CreateWebhookSubscription(WebhookSubscriptionCreateDto dto) | |||||
| { | |||||
| // map dto to db model | |||||
| WebhookSubscription subscription = _mapper.Map<WebhookSubscription>(dto); | |||||
| subscription.CreatedAtUtc = DateTime.UtcNow; | |||||
| subscription.IsActive = true; | |||||
| // add to db | |||||
| await _context.WebhookSubscriptions.AddAsync(subscription); | |||||
| await _context.SaveChangesAsync(); | |||||
| return subscription; | |||||
| } | |||||
| public async Task<List<WebhookSubscription>> GetAllSubscriptionsAsync(string webhookName) | |||||
| { | |||||
| return await _context.WebhookSubscriptions | |||||
| .Where(x => x.WebhookDefinition.Name == webhookName) | |||||
| .Include(x => x.WebhookDefinition) | |||||
| .ToListAsync(); | |||||
| } | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Business.Settings | |||||
| { | |||||
| public class AuthorizationSettings | |||||
| { | |||||
| public string Secret { get; set; } | |||||
| } | |||||
| } |
| global using Diligent.WebAPI.Business.Services.Interfaces; | |||||
| global using Diligent.WebAPI.Business.Settings; | |||||
| global using Diligent.WebAPI.Data; | |||||
| global using Diligent.WebAPI.Data.Entities; | |||||
| global using Diligent.WebAPI.Contracts.DTOs.InsuranceCompany; | |||||
| global using Diligent.WebAPI.Contracts.DTOs.InsurancePolicy; | |||||
| global using Diligent.WebAPI.Contracts.DTOs.Insurer; | |||||
| global using Diligent.WebAPI.Contracts.DTOs.WebhookDefinition; | |||||
| global using Diligent.WebAPI.Contracts.DTOs.WebhookSubscription; | |||||
| global using Diligent.WebAPI.Contracts.DTOs.Auth; | |||||
| global using Diligent.WebAPI.Contracts.Exceptions; | |||||
| global using Microsoft.EntityFrameworkCore; | |||||
| global using Microsoft.Extensions.Options; | |||||
| global using Microsoft.IdentityModel.Tokens; | |||||
| global using System.IdentityModel.Tokens.Jwt; | |||||
| global using System.Security.Claims; | |||||
| global using System.Text; | |||||
| global using Newtonsoft.Json; | |||||
| global using RestSharp; | |||||
| global using AutoMapper; |
| namespace Diligent.WebAPI.Contracts.DTOs.Auth | |||||
| { | |||||
| public class AuthenticateRequestDto | |||||
| { | |||||
| [Required] | |||||
| public string Username { get; set; } | |||||
| [Required] | |||||
| public string Password { get; set; } | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Contracts.DTOs.Auth | |||||
| { | |||||
| public class AuthenticateResponseDto | |||||
| { | |||||
| public long Id { get; set; } | |||||
| public string FirstName { get; set; } | |||||
| public string LastName { get; set; } | |||||
| public string Username { get; set; } | |||||
| public string Token { get; set; } | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Contracts.DTOs.Error | |||||
| { | |||||
| public class ErrorResponseDto | |||||
| { | |||||
| public string Message { get; set; } | |||||
| public List<ValidationItemDto> ValidationItems { get; set; } = new List<ValidationItemDto>(); | |||||
| public ErrorResponseDto(string message) | |||||
| { | |||||
| Message = message; | |||||
| } | |||||
| public ErrorResponseDto(string message, List<ValidationItemDto> validationItems) | |||||
| { | |||||
| Message = message; | |||||
| ValidationItems = validationItems; | |||||
| } | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Contracts.DTOs.Error | |||||
| { | |||||
| public class ValidationItemDto | |||||
| { | |||||
| public string Key { get; set; } | |||||
| public string? Value { get; set; } | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Contracts.DTOs.InsuranceCompany | |||||
| { | |||||
| public class InsuranceCompanyCreateDto | |||||
| { | |||||
| [Required] | |||||
| public string Name { get; set; } | |||||
| [DataType(DataType.PhoneNumber)] | |||||
| [RegularExpression(@"^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$", ErrorMessage = "Not a valid phone number")] | |||||
| public string? PhoneNumber { get; set; } | |||||
| public string? Fax { get; set; } | |||||
| public string? City { get; set; } | |||||
| public string? Country { get; set; } | |||||
| [RegularExpression(@"^\d{5}(-\d{4})?$", ErrorMessage = "Invalid Postal Code")] | |||||
| public string? PostalCode { get; set; } | |||||
| public string? LegalAddress { get; set; } | |||||
| [RegularExpression(@"^([\w\.\-]+)@([\w\-]+)((\.(\w){2,3})+)$", ErrorMessage = "Invalid email address")] | |||||
| public string? LegalEmail { get; set; } | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Contracts.DTOs.InsuranceCompany | |||||
| { | |||||
| public class InsuranceCompanyUpdateDto | |||||
| { | |||||
| public string Name { get; set; } | |||||
| public string PhoneNumber { get; set; } | |||||
| public string Fax { get; set; } | |||||
| public string City { get; set; } | |||||
| public string Country { get; set; } | |||||
| public string PostalCode { get; set; } | |||||
| public string LegalAddress { get; set; } | |||||
| public string LegalEmail { get; set; } | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Contracts.DTOs.InsuranceCompany | |||||
| { | |||||
| public class InsuranceCompanyViewDto | |||||
| { | |||||
| public long Id { get; set; } | |||||
| public DateTime CreatedAtUtc { get; set; } | |||||
| public DateTime? UpdatedAtUtc { get; set; } | |||||
| public DateTime? DeletedAtUtc { get; set; } | |||||
| public string Name { get; set; } | |||||
| public string PhoneNumber { get; set; } | |||||
| public string Fax { get; set; } | |||||
| public string City { get; set; } | |||||
| public string Country { get; set; } | |||||
| public string PostalCode { get; set; } | |||||
| public string LegalAddress { get; set; } | |||||
| public string LegalEmail { get; set; } | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Contracts.DTOs.InsurancePolicy | |||||
| { | |||||
| public class InsurancePolicyCreateDto | |||||
| { | |||||
| public decimal Premium { get; set; } | |||||
| public DateTime StartDate { get; set; } | |||||
| public DateTime EndDate { get; set; } | |||||
| public string Type { get; set; } | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Contracts.DTOs.InsurancePolicy | |||||
| { | |||||
| public class InsurancePolicyUpdateDto | |||||
| { | |||||
| public decimal Premium { get; set; } | |||||
| public DateTime StartDate { get; set; } | |||||
| public DateTime EndDate { get; set; } | |||||
| public string Type { get; set; } | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Contracts.DTOs.InsurancePolicy | |||||
| { | |||||
| public class InsurancePolicyViewDto | |||||
| { | |||||
| public int Id { get; set; } | |||||
| public decimal Premium { get; set; } | |||||
| public DateTime StartDate { get; set; } | |||||
| public DateTime EndDate { get; set; } | |||||
| public string Type { get; set; } | |||||
| //public long InsurerId { get; set; } | |||||
| //public virtual Insurer Insurer { get; set; } | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Contracts.DTOs.Insurer | |||||
| { | |||||
| public class InsurerCreateDto | |||||
| { | |||||
| public string FirstName { get; set; } | |||||
| public string LastName { get; set; } | |||||
| public DateTime DateOfBirth { get; set; } | |||||
| public string PhoneNumber { get; set; } | |||||
| public string City { get; set; } | |||||
| public string Country { get; set; } | |||||
| public string PostalCode { get; set; } | |||||
| public string Address { get; set; } | |||||
| public string Email { get; set; } | |||||
| public long InsuranceCompanyId { get; set; } | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Contracts.DTOs.Insurer | |||||
| { | |||||
| public class InsurerUpdateDto | |||||
| { | |||||
| public string FirstName { get; set; } | |||||
| public string LastName { get; set; } | |||||
| public DateTime DateOfBirth { get; set; } | |||||
| public string PhoneNumber { get; set; } | |||||
| public string City { get; set; } | |||||
| public string Country { get; set; } | |||||
| public string PostalCode { get; set; } | |||||
| public string Address { get; set; } | |||||
| public string Email { get; set; } | |||||
| public long InsuranceCompanyId { get; set; } | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Contracts.DTOs.Insurer | |||||
| { | |||||
| public class InsurerViewDto | |||||
| { | |||||
| public long Id { get; set; } | |||||
| public string FirstName { get; set; } | |||||
| public string LastName { get; set; } | |||||
| public DateTime DateOfBirth { get; set; } | |||||
| public string PhoneNumber { get; set; } | |||||
| public string City { get; set; } | |||||
| public string Country { get; set; } | |||||
| public string PostalCode { get; set; } | |||||
| public string Address { get; set; } | |||||
| public string Email { get; set; } | |||||
| public InsuranceCompanyViewDto InsuranceCompany { get; set; } | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Contracts.DTOs.WebhookDefinition | |||||
| { | |||||
| public class WebhookDefinitionViewDto | |||||
| { | |||||
| public long Id { get; set; } | |||||
| public string Name { get; set; } | |||||
| public string DisplayName { get; set; } | |||||
| public string Description { get; set; } | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Contracts.DTOs.WebhookSubscription | |||||
| { | |||||
| public class WebhookSubscriptionCreateDto | |||||
| { | |||||
| [Required] | |||||
| public string WebhookUri { get; set; } | |||||
| [Required] | |||||
| public long WebhookDefinitionId { get; set; } | |||||
| } | |||||
| } |
| <Project Sdk="Microsoft.NET.Sdk"> | |||||
| <PropertyGroup> | |||||
| <TargetFramework>net6.0</TargetFramework> | |||||
| <ImplicitUsings>enable</ImplicitUsings> | |||||
| <Nullable>enable</Nullable> | |||||
| </PropertyGroup> | |||||
| <ItemGroup> | |||||
| <ProjectReference Include="..\Diligent.WebAPI.Data\Diligent.WebAPI.Data.csproj" /> | |||||
| </ItemGroup> | |||||
| </Project> |
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Linq; | |||||
| using System.Text; | |||||
| using System.Threading.Tasks; | |||||
| namespace Diligent.WebAPI.Contracts.Exceptions | |||||
| { | |||||
| public class EntityNotFoundException : Exception | |||||
| { | |||||
| public EntityNotFoundException() | |||||
| { | |||||
| } | |||||
| public EntityNotFoundException(string message) | |||||
| : base(message) | |||||
| { | |||||
| } | |||||
| public EntityNotFoundException(string message, Exception inner) | |||||
| : base(message, inner) | |||||
| { | |||||
| } | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Contracts.Models | |||||
| { | |||||
| public class BaseResult<T> where T : class | |||||
| { | |||||
| public bool IsSuccess { get; set; } = true; | |||||
| public T DataObject { get; set; } | |||||
| public IList<ResultError> Errors { get; set; } = new List<ResultError>(); | |||||
| public void Add400BadRequestError(string name, string message) | |||||
| { | |||||
| var error = new ResultError() | |||||
| { | |||||
| Name = name | |||||
| }; | |||||
| error.Add400BadRequestError(message); | |||||
| Errors.Add(error); | |||||
| } | |||||
| public void Add404NotFoundError(string name, string message) | |||||
| { | |||||
| var error = new ResultError() | |||||
| { | |||||
| Name = name | |||||
| }; | |||||
| error.Add404NotFoundError(message); | |||||
| Errors.Add(error); | |||||
| } | |||||
| public void Add409ConflictError(string name, string message) | |||||
| { | |||||
| var error = new ResultError() | |||||
| { | |||||
| Name = name | |||||
| }; | |||||
| error.Add409ConflictError(message); | |||||
| Errors.Add(error); | |||||
| } | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Contracts.Models | |||||
| { | |||||
| public class HttpResultError | |||||
| { | |||||
| public HttpStatusCode ErrorCode { get; set; } | |||||
| public string ErrorMessage { get; set; } | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Contracts.Models | |||||
| { | |||||
| public class ResultError | |||||
| { | |||||
| public string Name { get; set; } | |||||
| public IList<HttpResultError> Messages { get; set; } = new List<HttpResultError>(); | |||||
| public ResultError() | |||||
| { | |||||
| } | |||||
| public ResultError(string name) | |||||
| { | |||||
| Name = name; | |||||
| } | |||||
| public void Add400BadRequestError(string message) | |||||
| { | |||||
| Messages.Add(new HttpResultError | |||||
| { | |||||
| ErrorCode = HttpStatusCode.BadRequest, | |||||
| ErrorMessage = message | |||||
| }); | |||||
| } | |||||
| public void Add404NotFoundError(string message) | |||||
| { | |||||
| Messages.Add(new HttpResultError | |||||
| { | |||||
| ErrorCode = HttpStatusCode.NotFound, | |||||
| ErrorMessage = message | |||||
| }); | |||||
| } | |||||
| public void Add409ConflictError(string message) | |||||
| { | |||||
| Messages.Add(new HttpResultError | |||||
| { | |||||
| ErrorCode = HttpStatusCode.Conflict, | |||||
| ErrorMessage = message | |||||
| }); | |||||
| } | |||||
| public void AddCustomError(HttpResultError error) | |||||
| { | |||||
| Messages.Add(error); | |||||
| } | |||||
| } | |||||
| } |
| global using System.Net; | |||||
| global using Diligent.WebAPI.Contracts.DTOs.InsuranceCompany; | |||||
| global using System.ComponentModel.DataAnnotations; |
| namespace Diligent.WebAPI.Data; | |||||
| public class DatabaseContext : DbContext | |||||
| { | |||||
| public DbSet<InsuranceCompany> InsuranceCompanies { get; set; } | |||||
| public DbSet<Insurer> Insurers { get; set; } | |||||
| public DbSet<InsurancePolicy> InsurancePolicies { get; set; } | |||||
| public DbSet<WebhookSubscription> WebhookSubscriptions { get; set; } | |||||
| public DbSet<WebhookDefinition> WebhookDefinitions { get; set; } | |||||
| public DatabaseContext(DbContextOptions<DatabaseContext> options) : base(options) { } | |||||
| protected override void OnModelCreating(ModelBuilder modelBuilder) | |||||
| { | |||||
| base.OnModelCreating(modelBuilder); | |||||
| } | |||||
| } |
| <Project Sdk="Microsoft.NET.Sdk"> | |||||
| <PropertyGroup> | |||||
| <TargetFramework>net6.0</TargetFramework> | |||||
| <ImplicitUsings>enable</ImplicitUsings> | |||||
| <Nullable>enable</Nullable> | |||||
| </PropertyGroup> | |||||
| <ItemGroup> | |||||
| <PackageReference Include="AutoMapper" Version="11.0.1" /> | |||||
| <PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="11.0.0" /> | |||||
| <PackageReference Include="Microsoft.AspNetCore" Version="2.2.0" /> | |||||
| <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.3" /> | |||||
| <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.3"> | |||||
| <PrivateAssets>all</PrivateAssets> | |||||
| <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | |||||
| </PackageReference> | |||||
| </ItemGroup> | |||||
| <ItemGroup> | |||||
| <Folder Include="Migrations\" /> | |||||
| </ItemGroup> | |||||
| </Project> |
| namespace Diligent.WebAPI.Data.Entities; | |||||
| public class Base | |||||
| { | |||||
| public long Id { get; set; } | |||||
| public DateTime CreatedAtUtc { get; set; } | |||||
| public DateTime? UpdatedAtUtc { get; set; } | |||||
| public DateTime? DeletedAtUtc { get; set; } | |||||
| } |
| namespace Diligent.WebAPI.Data.Entities; | |||||
| public class InsuranceCompany : Base | |||||
| { | |||||
| public string Name { get; set; } | |||||
| public string PhoneNumber { get; set; } | |||||
| public string Fax { get; set; } | |||||
| public string City { get; set; } | |||||
| public string Country { get; set; } | |||||
| public string PostalCode { get; set; } | |||||
| public string LegalAddress { get; set; } | |||||
| public string LegalEmail { get; set; } | |||||
| } |
| namespace Diligent.WebAPI.Data.Entities; | |||||
| public class InsurancePolicy : Base | |||||
| { | |||||
| public decimal Premium { get; set; } | |||||
| public DateTime StartDate { get; set; } | |||||
| public DateTime EndDate { get; set; } | |||||
| public string Type { get; set; } | |||||
| public long InsurerId { get; set; } | |||||
| public virtual Insurer Insurer { get; set; } | |||||
| } |
| namespace Diligent.WebAPI.Data.Entities; | |||||
| public class Insurer : Base | |||||
| { | |||||
| [Required] | |||||
| public string FirstName { get; set; } | |||||
| public string LastName { get; set; } | |||||
| public DateTime DateOfBirth { get; set; } | |||||
| public string PhoneNumber { get; set; } | |||||
| public string City { get; set; } | |||||
| public string Country { get; set; } | |||||
| public string PostalCode { get; set; } | |||||
| public string Address { get; set; } | |||||
| public string Email { get; set; } | |||||
| public long InsuranceCompanyId { get; set; } | |||||
| public virtual InsuranceCompany InsuranceCompany { get; set; } | |||||
| } |
| namespace Diligent.WebAPI.Data.Entities; | |||||
| public class User : Base | |||||
| { | |||||
| public string FirstName { get; set; } | |||||
| public string LastName { get; set; } | |||||
| public string Username { get; set; } | |||||
| public string Password { get; set; } | |||||
| } |
| namespace Diligent.WebAPI.Data.Entities | |||||
| { | |||||
| public class WebhookDefinition : Base | |||||
| { | |||||
| [Required] | |||||
| [MaxLength(100)] | |||||
| public string Name { get; set; } // example: insuranceCompany.Created | |||||
| [MaxLength(100)] | |||||
| public string DisplayName { get; set; } | |||||
| public string Description { get; set; } | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Data.Entities | |||||
| { | |||||
| public class WebhookSubscription : Base | |||||
| { | |||||
| public string WebhookURL { get; set; } | |||||
| public bool IsActive { get; set; } | |||||
| public long WebhookDefinitionId { get; set; } | |||||
| public virtual WebhookDefinition WebhookDefinition { get; set; } | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Data.Extensions; | |||||
| public static class ServiceCollection | |||||
| { | |||||
| public static void ConfigureData(this IServiceCollection services, IConfiguration configuration) | |||||
| { | |||||
| services.AddDbContext<DatabaseContext>(options => | |||||
| { | |||||
| if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development") | |||||
| { | |||||
| options.EnableSensitiveDataLogging(); | |||||
| } | |||||
| options.UseSqlServer(configuration.GetConnectionString(nameof(Diligent.WebAPI))); | |||||
| }); | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Data.Extensions; | |||||
| public static class ServiceScope | |||||
| { | |||||
| public static void SetupData(this IServiceScope scope) | |||||
| { | |||||
| var dbContext = scope.ServiceProvider.GetRequiredService<DatabaseContext>(); | |||||
| if (dbContext.Database.GetPendingMigrations().Any()) | |||||
| { | |||||
| dbContext.Database.Migrate(); | |||||
| } | |||||
| } | |||||
| } |
| // <auto-generated /> | |||||
| using System; | |||||
| using Diligent.WebAPI.Data; | |||||
| using Microsoft.EntityFrameworkCore; | |||||
| using Microsoft.EntityFrameworkCore.Infrastructure; | |||||
| using Microsoft.EntityFrameworkCore.Metadata; | |||||
| using Microsoft.EntityFrameworkCore.Migrations; | |||||
| using Microsoft.EntityFrameworkCore.Storage.ValueConversion; | |||||
| #nullable disable | |||||
| namespace Diligent.WebAPI.Data.Migrations | |||||
| { | |||||
| [DbContext(typeof(DatabaseContext))] | |||||
| [Migration("20220331142133_Initial")] | |||||
| partial class Initial | |||||
| { | |||||
| protected override void BuildTargetModel(ModelBuilder modelBuilder) | |||||
| { | |||||
| #pragma warning disable 612, 618 | |||||
| modelBuilder | |||||
| .HasAnnotation("ProductVersion", "6.0.3") | |||||
| .HasAnnotation("Relational:MaxIdentifierLength", 128); | |||||
| SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1); | |||||
| modelBuilder.Entity("Diligent.WebAPI.Data.Entities.InsuranceCompany", b => | |||||
| { | |||||
| b.Property<long>("Id") | |||||
| .ValueGeneratedOnAdd() | |||||
| .HasColumnType("bigint"); | |||||
| SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("Id"), 1L, 1); | |||||
| b.Property<string>("City") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.Property<string>("Country") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.Property<DateTime>("CreatedAtUtc") | |||||
| .HasColumnType("datetime2"); | |||||
| b.Property<DateTime?>("DeletedAtUtc") | |||||
| .HasColumnType("datetime2"); | |||||
| b.Property<string>("Fax") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.Property<string>("LegalAddress") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.Property<string>("LegalEmail") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.Property<string>("Name") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.Property<string>("PhoneNumber") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.Property<string>("PostalCode") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.Property<DateTime?>("UpdatedAtUtc") | |||||
| .HasColumnType("datetime2"); | |||||
| b.HasKey("Id"); | |||||
| b.ToTable("InsuranceCompanies"); | |||||
| }); | |||||
| modelBuilder.Entity("Diligent.WebAPI.Data.Entities.InsurancePolicy", b => | |||||
| { | |||||
| b.Property<long>("Id") | |||||
| .ValueGeneratedOnAdd() | |||||
| .HasColumnType("bigint"); | |||||
| SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("Id"), 1L, 1); | |||||
| b.Property<DateTime>("CreatedAtUtc") | |||||
| .HasColumnType("datetime2"); | |||||
| b.Property<DateTime?>("DeletedAtUtc") | |||||
| .HasColumnType("datetime2"); | |||||
| b.Property<DateTime>("EndDate") | |||||
| .HasColumnType("datetime2"); | |||||
| b.Property<long>("InsurerId") | |||||
| .HasColumnType("bigint"); | |||||
| b.Property<decimal>("Premium") | |||||
| .HasColumnType("decimal(18,2)"); | |||||
| b.Property<DateTime>("StartDate") | |||||
| .HasColumnType("datetime2"); | |||||
| b.Property<string>("Type") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.Property<DateTime?>("UpdatedAtUtc") | |||||
| .HasColumnType("datetime2"); | |||||
| b.HasKey("Id"); | |||||
| b.HasIndex("InsurerId"); | |||||
| b.ToTable("InsurancePolicies"); | |||||
| }); | |||||
| modelBuilder.Entity("Diligent.WebAPI.Data.Entities.Insurer", b => | |||||
| { | |||||
| b.Property<long>("Id") | |||||
| .ValueGeneratedOnAdd() | |||||
| .HasColumnType("bigint"); | |||||
| SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("Id"), 1L, 1); | |||||
| b.Property<string>("Address") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.Property<string>("City") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.Property<string>("Country") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.Property<DateTime>("CreatedAtUtc") | |||||
| .HasColumnType("datetime2"); | |||||
| b.Property<DateTime>("DateOfBirth") | |||||
| .HasColumnType("datetime2"); | |||||
| b.Property<DateTime?>("DeletedAtUtc") | |||||
| .HasColumnType("datetime2"); | |||||
| b.Property<string>("Email") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.Property<string>("FirstName") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.Property<long>("InsuranceCompanyId") | |||||
| .HasColumnType("bigint"); | |||||
| b.Property<string>("LastName") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.Property<string>("PhoneNumber") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.Property<string>("PostalCode") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.Property<DateTime?>("UpdatedAtUtc") | |||||
| .HasColumnType("datetime2"); | |||||
| b.HasKey("Id"); | |||||
| b.HasIndex("InsuranceCompanyId"); | |||||
| b.ToTable("Insurers"); | |||||
| }); | |||||
| modelBuilder.Entity("Diligent.WebAPI.Data.Entities.InsurancePolicy", b => | |||||
| { | |||||
| b.HasOne("Diligent.WebAPI.Data.Entities.Insurer", "Insurer") | |||||
| .WithMany() | |||||
| .HasForeignKey("InsurerId") | |||||
| .OnDelete(DeleteBehavior.Cascade) | |||||
| .IsRequired(); | |||||
| b.Navigation("Insurer"); | |||||
| }); | |||||
| modelBuilder.Entity("Diligent.WebAPI.Data.Entities.Insurer", b => | |||||
| { | |||||
| b.HasOne("Diligent.WebAPI.Data.Entities.InsuranceCompany", "InsuranceCompany") | |||||
| .WithMany() | |||||
| .HasForeignKey("InsuranceCompanyId") | |||||
| .OnDelete(DeleteBehavior.Cascade) | |||||
| .IsRequired(); | |||||
| b.Navigation("InsuranceCompany"); | |||||
| }); | |||||
| #pragma warning restore 612, 618 | |||||
| } | |||||
| } | |||||
| } |
| using System; | |||||
| using Microsoft.EntityFrameworkCore.Migrations; | |||||
| #nullable disable | |||||
| namespace Diligent.WebAPI.Data.Migrations | |||||
| { | |||||
| public partial class Initial : Migration | |||||
| { | |||||
| protected override void Up(MigrationBuilder migrationBuilder) | |||||
| { | |||||
| migrationBuilder.CreateTable( | |||||
| name: "InsuranceCompanies", | |||||
| columns: table => new | |||||
| { | |||||
| Id = table.Column<long>(type: "bigint", nullable: false) | |||||
| .Annotation("SqlServer:Identity", "1, 1"), | |||||
| Name = table.Column<string>(type: "nvarchar(max)", nullable: false), | |||||
| PhoneNumber = table.Column<string>(type: "nvarchar(max)", nullable: false), | |||||
| Fax = table.Column<string>(type: "nvarchar(max)", nullable: false), | |||||
| City = table.Column<string>(type: "nvarchar(max)", nullable: false), | |||||
| Country = table.Column<string>(type: "nvarchar(max)", nullable: false), | |||||
| PostalCode = table.Column<string>(type: "nvarchar(max)", nullable: false), | |||||
| LegalAddress = table.Column<string>(type: "nvarchar(max)", nullable: false), | |||||
| LegalEmail = table.Column<string>(type: "nvarchar(max)", nullable: false), | |||||
| CreatedAtUtc = table.Column<DateTime>(type: "datetime2", nullable: false), | |||||
| UpdatedAtUtc = table.Column<DateTime>(type: "datetime2", nullable: true), | |||||
| DeletedAtUtc = table.Column<DateTime>(type: "datetime2", nullable: true) | |||||
| }, | |||||
| constraints: table => | |||||
| { | |||||
| table.PrimaryKey("PK_InsuranceCompanies", x => x.Id); | |||||
| }); | |||||
| migrationBuilder.CreateTable( | |||||
| name: "Insurers", | |||||
| columns: table => new | |||||
| { | |||||
| Id = table.Column<long>(type: "bigint", nullable: false) | |||||
| .Annotation("SqlServer:Identity", "1, 1"), | |||||
| FirstName = table.Column<string>(type: "nvarchar(max)", nullable: false), | |||||
| LastName = table.Column<string>(type: "nvarchar(max)", nullable: false), | |||||
| DateOfBirth = table.Column<DateTime>(type: "datetime2", nullable: false), | |||||
| PhoneNumber = table.Column<string>(type: "nvarchar(max)", nullable: false), | |||||
| City = table.Column<string>(type: "nvarchar(max)", nullable: false), | |||||
| Country = table.Column<string>(type: "nvarchar(max)", nullable: false), | |||||
| PostalCode = table.Column<string>(type: "nvarchar(max)", nullable: false), | |||||
| Address = table.Column<string>(type: "nvarchar(max)", nullable: false), | |||||
| Email = table.Column<string>(type: "nvarchar(max)", nullable: false), | |||||
| InsuranceCompanyId = table.Column<long>(type: "bigint", nullable: false), | |||||
| CreatedAtUtc = table.Column<DateTime>(type: "datetime2", nullable: false), | |||||
| UpdatedAtUtc = table.Column<DateTime>(type: "datetime2", nullable: true), | |||||
| DeletedAtUtc = table.Column<DateTime>(type: "datetime2", nullable: true) | |||||
| }, | |||||
| constraints: table => | |||||
| { | |||||
| table.PrimaryKey("PK_Insurers", x => x.Id); | |||||
| table.ForeignKey( | |||||
| name: "FK_Insurers_InsuranceCompanies_InsuranceCompanyId", | |||||
| column: x => x.InsuranceCompanyId, | |||||
| principalTable: "InsuranceCompanies", | |||||
| principalColumn: "Id", | |||||
| onDelete: ReferentialAction.Cascade); | |||||
| }); | |||||
| migrationBuilder.CreateTable( | |||||
| name: "InsurancePolicies", | |||||
| columns: table => new | |||||
| { | |||||
| Id = table.Column<long>(type: "bigint", nullable: false) | |||||
| .Annotation("SqlServer:Identity", "1, 1"), | |||||
| Premium = table.Column<decimal>(type: "decimal(18,2)", nullable: false), | |||||
| StartDate = table.Column<DateTime>(type: "datetime2", nullable: false), | |||||
| EndDate = table.Column<DateTime>(type: "datetime2", nullable: false), | |||||
| Type = table.Column<string>(type: "nvarchar(max)", nullable: false), | |||||
| InsurerId = table.Column<long>(type: "bigint", nullable: false), | |||||
| CreatedAtUtc = table.Column<DateTime>(type: "datetime2", nullable: false), | |||||
| UpdatedAtUtc = table.Column<DateTime>(type: "datetime2", nullable: true), | |||||
| DeletedAtUtc = table.Column<DateTime>(type: "datetime2", nullable: true) | |||||
| }, | |||||
| constraints: table => | |||||
| { | |||||
| table.PrimaryKey("PK_InsurancePolicies", x => x.Id); | |||||
| table.ForeignKey( | |||||
| name: "FK_InsurancePolicies_Insurers_InsurerId", | |||||
| column: x => x.InsurerId, | |||||
| principalTable: "Insurers", | |||||
| principalColumn: "Id", | |||||
| onDelete: ReferentialAction.Cascade); | |||||
| }); | |||||
| migrationBuilder.CreateIndex( | |||||
| name: "IX_InsurancePolicies_InsurerId", | |||||
| table: "InsurancePolicies", | |||||
| column: "InsurerId"); | |||||
| migrationBuilder.CreateIndex( | |||||
| name: "IX_Insurers_InsuranceCompanyId", | |||||
| table: "Insurers", | |||||
| column: "InsuranceCompanyId"); | |||||
| } | |||||
| protected override void Down(MigrationBuilder migrationBuilder) | |||||
| { | |||||
| migrationBuilder.DropTable( | |||||
| name: "InsurancePolicies"); | |||||
| migrationBuilder.DropTable( | |||||
| name: "Insurers"); | |||||
| migrationBuilder.DropTable( | |||||
| name: "InsuranceCompanies"); | |||||
| } | |||||
| } | |||||
| } |
| // <auto-generated /> | |||||
| using System; | |||||
| using Diligent.WebAPI.Data; | |||||
| using Microsoft.EntityFrameworkCore; | |||||
| using Microsoft.EntityFrameworkCore.Infrastructure; | |||||
| using Microsoft.EntityFrameworkCore.Metadata; | |||||
| using Microsoft.EntityFrameworkCore.Migrations; | |||||
| using Microsoft.EntityFrameworkCore.Storage.ValueConversion; | |||||
| #nullable disable | |||||
| namespace Diligent.WebAPI.Data.Migrations | |||||
| { | |||||
| [DbContext(typeof(DatabaseContext))] | |||||
| [Migration("20220815162411_AddedWebhookTables")] | |||||
| partial class AddedWebhookTables | |||||
| { | |||||
| protected override void BuildTargetModel(ModelBuilder modelBuilder) | |||||
| { | |||||
| #pragma warning disable 612, 618 | |||||
| modelBuilder | |||||
| .HasAnnotation("ProductVersion", "6.0.3") | |||||
| .HasAnnotation("Relational:MaxIdentifierLength", 128); | |||||
| SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1); | |||||
| modelBuilder.Entity("Diligent.WebAPI.Data.Entities.InsuranceCompany", b => | |||||
| { | |||||
| b.Property<long>("Id") | |||||
| .ValueGeneratedOnAdd() | |||||
| .HasColumnType("bigint"); | |||||
| SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("Id"), 1L, 1); | |||||
| b.Property<string>("City") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.Property<string>("Country") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.Property<DateTime>("CreatedAtUtc") | |||||
| .HasColumnType("datetime2"); | |||||
| b.Property<DateTime?>("DeletedAtUtc") | |||||
| .HasColumnType("datetime2"); | |||||
| b.Property<string>("Fax") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.Property<string>("LegalAddress") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.Property<string>("LegalEmail") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.Property<string>("Name") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.Property<string>("PhoneNumber") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.Property<string>("PostalCode") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.Property<DateTime?>("UpdatedAtUtc") | |||||
| .HasColumnType("datetime2"); | |||||
| b.HasKey("Id"); | |||||
| b.ToTable("InsuranceCompanies"); | |||||
| }); | |||||
| modelBuilder.Entity("Diligent.WebAPI.Data.Entities.InsurancePolicy", b => | |||||
| { | |||||
| b.Property<long>("Id") | |||||
| .ValueGeneratedOnAdd() | |||||
| .HasColumnType("bigint"); | |||||
| SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("Id"), 1L, 1); | |||||
| b.Property<DateTime>("CreatedAtUtc") | |||||
| .HasColumnType("datetime2"); | |||||
| b.Property<DateTime?>("DeletedAtUtc") | |||||
| .HasColumnType("datetime2"); | |||||
| b.Property<DateTime>("EndDate") | |||||
| .HasColumnType("datetime2"); | |||||
| b.Property<long>("InsurerId") | |||||
| .HasColumnType("bigint"); | |||||
| b.Property<decimal>("Premium") | |||||
| .HasColumnType("decimal(18,2)"); | |||||
| b.Property<DateTime>("StartDate") | |||||
| .HasColumnType("datetime2"); | |||||
| b.Property<string>("Type") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.Property<DateTime?>("UpdatedAtUtc") | |||||
| .HasColumnType("datetime2"); | |||||
| b.HasKey("Id"); | |||||
| b.HasIndex("InsurerId"); | |||||
| b.ToTable("InsurancePolicies"); | |||||
| }); | |||||
| modelBuilder.Entity("Diligent.WebAPI.Data.Entities.Insurer", b => | |||||
| { | |||||
| b.Property<long>("Id") | |||||
| .ValueGeneratedOnAdd() | |||||
| .HasColumnType("bigint"); | |||||
| SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("Id"), 1L, 1); | |||||
| b.Property<string>("Address") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.Property<string>("City") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.Property<string>("Country") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.Property<DateTime>("CreatedAtUtc") | |||||
| .HasColumnType("datetime2"); | |||||
| b.Property<DateTime>("DateOfBirth") | |||||
| .HasColumnType("datetime2"); | |||||
| b.Property<DateTime?>("DeletedAtUtc") | |||||
| .HasColumnType("datetime2"); | |||||
| b.Property<string>("Email") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.Property<string>("FirstName") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.Property<long>("InsuranceCompanyId") | |||||
| .HasColumnType("bigint"); | |||||
| b.Property<string>("LastName") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.Property<string>("PhoneNumber") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.Property<string>("PostalCode") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.Property<DateTime?>("UpdatedAtUtc") | |||||
| .HasColumnType("datetime2"); | |||||
| b.HasKey("Id"); | |||||
| b.HasIndex("InsuranceCompanyId"); | |||||
| b.ToTable("Insurers"); | |||||
| }); | |||||
| modelBuilder.Entity("Diligent.WebAPI.Data.Entities.WebhookDefinition", b => | |||||
| { | |||||
| b.Property<long>("Id") | |||||
| .ValueGeneratedOnAdd() | |||||
| .HasColumnType("bigint"); | |||||
| SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("Id"), 1L, 1); | |||||
| b.Property<DateTime>("CreatedAtUtc") | |||||
| .HasColumnType("datetime2"); | |||||
| b.Property<DateTime?>("DeletedAtUtc") | |||||
| .HasColumnType("datetime2"); | |||||
| b.Property<string>("Description") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.Property<string>("DisplayName") | |||||
| .IsRequired() | |||||
| .HasMaxLength(100) | |||||
| .HasColumnType("nvarchar(100)"); | |||||
| b.Property<string>("Name") | |||||
| .IsRequired() | |||||
| .HasMaxLength(100) | |||||
| .HasColumnType("nvarchar(100)"); | |||||
| b.Property<DateTime?>("UpdatedAtUtc") | |||||
| .HasColumnType("datetime2"); | |||||
| b.HasKey("Id"); | |||||
| b.ToTable("WebhookDefinitions"); | |||||
| }); | |||||
| modelBuilder.Entity("Diligent.WebAPI.Data.Entities.WebhookSubscription", b => | |||||
| { | |||||
| b.Property<long>("Id") | |||||
| .ValueGeneratedOnAdd() | |||||
| .HasColumnType("bigint"); | |||||
| SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("Id"), 1L, 1); | |||||
| b.Property<DateTime>("CreatedAtUtc") | |||||
| .HasColumnType("datetime2"); | |||||
| b.Property<DateTime?>("DeletedAtUtc") | |||||
| .HasColumnType("datetime2"); | |||||
| b.Property<bool>("IsActive") | |||||
| .HasColumnType("bit"); | |||||
| b.Property<DateTime?>("UpdatedAtUtc") | |||||
| .HasColumnType("datetime2"); | |||||
| b.Property<long>("WebhookDefinitionId") | |||||
| .HasColumnType("bigint"); | |||||
| b.Property<string>("WebhookURL") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.HasKey("Id"); | |||||
| b.HasIndex("WebhookDefinitionId"); | |||||
| b.ToTable("WebhookSubscriptions"); | |||||
| }); | |||||
| modelBuilder.Entity("Diligent.WebAPI.Data.Entities.InsurancePolicy", b => | |||||
| { | |||||
| b.HasOne("Diligent.WebAPI.Data.Entities.Insurer", "Insurer") | |||||
| .WithMany() | |||||
| .HasForeignKey("InsurerId") | |||||
| .OnDelete(DeleteBehavior.Cascade) | |||||
| .IsRequired(); | |||||
| b.Navigation("Insurer"); | |||||
| }); | |||||
| modelBuilder.Entity("Diligent.WebAPI.Data.Entities.Insurer", b => | |||||
| { | |||||
| b.HasOne("Diligent.WebAPI.Data.Entities.InsuranceCompany", "InsuranceCompany") | |||||
| .WithMany() | |||||
| .HasForeignKey("InsuranceCompanyId") | |||||
| .OnDelete(DeleteBehavior.Cascade) | |||||
| .IsRequired(); | |||||
| b.Navigation("InsuranceCompany"); | |||||
| }); | |||||
| modelBuilder.Entity("Diligent.WebAPI.Data.Entities.WebhookSubscription", b => | |||||
| { | |||||
| b.HasOne("Diligent.WebAPI.Data.Entities.WebhookDefinition", "WebhookDefinition") | |||||
| .WithMany() | |||||
| .HasForeignKey("WebhookDefinitionId") | |||||
| .OnDelete(DeleteBehavior.Cascade) | |||||
| .IsRequired(); | |||||
| b.Navigation("WebhookDefinition"); | |||||
| }); | |||||
| #pragma warning restore 612, 618 | |||||
| } | |||||
| } | |||||
| } |
| using System; | |||||
| using Microsoft.EntityFrameworkCore.Migrations; | |||||
| #nullable disable | |||||
| namespace Diligent.WebAPI.Data.Migrations | |||||
| { | |||||
| public partial class AddedWebhookTables : Migration | |||||
| { | |||||
| protected override void Up(MigrationBuilder migrationBuilder) | |||||
| { | |||||
| migrationBuilder.CreateTable( | |||||
| name: "WebhookDefinitions", | |||||
| columns: table => new | |||||
| { | |||||
| Id = table.Column<long>(type: "bigint", nullable: false) | |||||
| .Annotation("SqlServer:Identity", "1, 1"), | |||||
| Name = table.Column<string>(type: "nvarchar(100)", maxLength: 100, nullable: false), | |||||
| DisplayName = table.Column<string>(type: "nvarchar(100)", maxLength: 100, nullable: false), | |||||
| Description = table.Column<string>(type: "nvarchar(max)", nullable: false), | |||||
| CreatedAtUtc = table.Column<DateTime>(type: "datetime2", nullable: false), | |||||
| UpdatedAtUtc = table.Column<DateTime>(type: "datetime2", nullable: true), | |||||
| DeletedAtUtc = table.Column<DateTime>(type: "datetime2", nullable: true) | |||||
| }, | |||||
| constraints: table => | |||||
| { | |||||
| table.PrimaryKey("PK_WebhookDefinitions", x => x.Id); | |||||
| }); | |||||
| migrationBuilder.CreateTable( | |||||
| name: "WebhookSubscriptions", | |||||
| columns: table => new | |||||
| { | |||||
| Id = table.Column<long>(type: "bigint", nullable: false) | |||||
| .Annotation("SqlServer:Identity", "1, 1"), | |||||
| WebhookURL = table.Column<string>(type: "nvarchar(max)", nullable: false), | |||||
| IsActive = table.Column<bool>(type: "bit", nullable: false), | |||||
| WebhookDefinitionId = table.Column<long>(type: "bigint", nullable: false), | |||||
| CreatedAtUtc = table.Column<DateTime>(type: "datetime2", nullable: false), | |||||
| UpdatedAtUtc = table.Column<DateTime>(type: "datetime2", nullable: true), | |||||
| DeletedAtUtc = table.Column<DateTime>(type: "datetime2", nullable: true) | |||||
| }, | |||||
| constraints: table => | |||||
| { | |||||
| table.PrimaryKey("PK_WebhookSubscriptions", x => x.Id); | |||||
| table.ForeignKey( | |||||
| name: "FK_WebhookSubscriptions_WebhookDefinitions_WebhookDefinitionId", | |||||
| column: x => x.WebhookDefinitionId, | |||||
| principalTable: "WebhookDefinitions", | |||||
| principalColumn: "Id", | |||||
| onDelete: ReferentialAction.Cascade); | |||||
| }); | |||||
| migrationBuilder.CreateIndex( | |||||
| name: "IX_WebhookSubscriptions_WebhookDefinitionId", | |||||
| table: "WebhookSubscriptions", | |||||
| column: "WebhookDefinitionId"); | |||||
| } | |||||
| protected override void Down(MigrationBuilder migrationBuilder) | |||||
| { | |||||
| migrationBuilder.DropTable( | |||||
| name: "WebhookSubscriptions"); | |||||
| migrationBuilder.DropTable( | |||||
| name: "WebhookDefinitions"); | |||||
| } | |||||
| } | |||||
| } |
| // <auto-generated /> | |||||
| using System; | |||||
| using Diligent.WebAPI.Data; | |||||
| using Microsoft.EntityFrameworkCore; | |||||
| using Microsoft.EntityFrameworkCore.Infrastructure; | |||||
| using Microsoft.EntityFrameworkCore.Metadata; | |||||
| using Microsoft.EntityFrameworkCore.Storage.ValueConversion; | |||||
| #nullable disable | |||||
| namespace Diligent.WebAPI.Data.Migrations | |||||
| { | |||||
| [DbContext(typeof(DatabaseContext))] | |||||
| partial class DatabaseContextModelSnapshot : ModelSnapshot | |||||
| { | |||||
| protected override void BuildModel(ModelBuilder modelBuilder) | |||||
| { | |||||
| #pragma warning disable 612, 618 | |||||
| modelBuilder | |||||
| .HasAnnotation("ProductVersion", "6.0.3") | |||||
| .HasAnnotation("Relational:MaxIdentifierLength", 128); | |||||
| SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1); | |||||
| modelBuilder.Entity("Diligent.WebAPI.Data.Entities.InsuranceCompany", b => | |||||
| { | |||||
| b.Property<long>("Id") | |||||
| .ValueGeneratedOnAdd() | |||||
| .HasColumnType("bigint"); | |||||
| SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("Id"), 1L, 1); | |||||
| b.Property<string>("City") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.Property<string>("Country") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.Property<DateTime>("CreatedAtUtc") | |||||
| .HasColumnType("datetime2"); | |||||
| b.Property<DateTime?>("DeletedAtUtc") | |||||
| .HasColumnType("datetime2"); | |||||
| b.Property<string>("Fax") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.Property<string>("LegalAddress") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.Property<string>("LegalEmail") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.Property<string>("Name") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.Property<string>("PhoneNumber") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.Property<string>("PostalCode") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.Property<DateTime?>("UpdatedAtUtc") | |||||
| .HasColumnType("datetime2"); | |||||
| b.HasKey("Id"); | |||||
| b.ToTable("InsuranceCompanies"); | |||||
| }); | |||||
| modelBuilder.Entity("Diligent.WebAPI.Data.Entities.InsurancePolicy", b => | |||||
| { | |||||
| b.Property<long>("Id") | |||||
| .ValueGeneratedOnAdd() | |||||
| .HasColumnType("bigint"); | |||||
| SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("Id"), 1L, 1); | |||||
| b.Property<DateTime>("CreatedAtUtc") | |||||
| .HasColumnType("datetime2"); | |||||
| b.Property<DateTime?>("DeletedAtUtc") | |||||
| .HasColumnType("datetime2"); | |||||
| b.Property<DateTime>("EndDate") | |||||
| .HasColumnType("datetime2"); | |||||
| b.Property<long>("InsurerId") | |||||
| .HasColumnType("bigint"); | |||||
| b.Property<decimal>("Premium") | |||||
| .HasColumnType("decimal(18,2)"); | |||||
| b.Property<DateTime>("StartDate") | |||||
| .HasColumnType("datetime2"); | |||||
| b.Property<string>("Type") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.Property<DateTime?>("UpdatedAtUtc") | |||||
| .HasColumnType("datetime2"); | |||||
| b.HasKey("Id"); | |||||
| b.HasIndex("InsurerId"); | |||||
| b.ToTable("InsurancePolicies"); | |||||
| }); | |||||
| modelBuilder.Entity("Diligent.WebAPI.Data.Entities.Insurer", b => | |||||
| { | |||||
| b.Property<long>("Id") | |||||
| .ValueGeneratedOnAdd() | |||||
| .HasColumnType("bigint"); | |||||
| SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("Id"), 1L, 1); | |||||
| b.Property<string>("Address") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.Property<string>("City") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.Property<string>("Country") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.Property<DateTime>("CreatedAtUtc") | |||||
| .HasColumnType("datetime2"); | |||||
| b.Property<DateTime>("DateOfBirth") | |||||
| .HasColumnType("datetime2"); | |||||
| b.Property<DateTime?>("DeletedAtUtc") | |||||
| .HasColumnType("datetime2"); | |||||
| b.Property<string>("Email") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.Property<string>("FirstName") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.Property<long>("InsuranceCompanyId") | |||||
| .HasColumnType("bigint"); | |||||
| b.Property<string>("LastName") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.Property<string>("PhoneNumber") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.Property<string>("PostalCode") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.Property<DateTime?>("UpdatedAtUtc") | |||||
| .HasColumnType("datetime2"); | |||||
| b.HasKey("Id"); | |||||
| b.HasIndex("InsuranceCompanyId"); | |||||
| b.ToTable("Insurers"); | |||||
| }); | |||||
| modelBuilder.Entity("Diligent.WebAPI.Data.Entities.WebhookDefinition", b => | |||||
| { | |||||
| b.Property<long>("Id") | |||||
| .ValueGeneratedOnAdd() | |||||
| .HasColumnType("bigint"); | |||||
| SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("Id"), 1L, 1); | |||||
| b.Property<DateTime>("CreatedAtUtc") | |||||
| .HasColumnType("datetime2"); | |||||
| b.Property<DateTime?>("DeletedAtUtc") | |||||
| .HasColumnType("datetime2"); | |||||
| b.Property<string>("Description") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.Property<string>("DisplayName") | |||||
| .IsRequired() | |||||
| .HasMaxLength(100) | |||||
| .HasColumnType("nvarchar(100)"); | |||||
| b.Property<string>("Name") | |||||
| .IsRequired() | |||||
| .HasMaxLength(100) | |||||
| .HasColumnType("nvarchar(100)"); | |||||
| b.Property<DateTime?>("UpdatedAtUtc") | |||||
| .HasColumnType("datetime2"); | |||||
| b.HasKey("Id"); | |||||
| b.ToTable("WebhookDefinitions"); | |||||
| }); | |||||
| modelBuilder.Entity("Diligent.WebAPI.Data.Entities.WebhookSubscription", b => | |||||
| { | |||||
| b.Property<long>("Id") | |||||
| .ValueGeneratedOnAdd() | |||||
| .HasColumnType("bigint"); | |||||
| SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("Id"), 1L, 1); | |||||
| b.Property<DateTime>("CreatedAtUtc") | |||||
| .HasColumnType("datetime2"); | |||||
| b.Property<DateTime?>("DeletedAtUtc") | |||||
| .HasColumnType("datetime2"); | |||||
| b.Property<bool>("IsActive") | |||||
| .HasColumnType("bit"); | |||||
| b.Property<DateTime?>("UpdatedAtUtc") | |||||
| .HasColumnType("datetime2"); | |||||
| b.Property<long>("WebhookDefinitionId") | |||||
| .HasColumnType("bigint"); | |||||
| b.Property<string>("WebhookURL") | |||||
| .IsRequired() | |||||
| .HasColumnType("nvarchar(max)"); | |||||
| b.HasKey("Id"); | |||||
| b.HasIndex("WebhookDefinitionId"); | |||||
| b.ToTable("WebhookSubscriptions"); | |||||
| }); | |||||
| modelBuilder.Entity("Diligent.WebAPI.Data.Entities.InsurancePolicy", b => | |||||
| { | |||||
| b.HasOne("Diligent.WebAPI.Data.Entities.Insurer", "Insurer") | |||||
| .WithMany() | |||||
| .HasForeignKey("InsurerId") | |||||
| .OnDelete(DeleteBehavior.Cascade) | |||||
| .IsRequired(); | |||||
| b.Navigation("Insurer"); | |||||
| }); | |||||
| modelBuilder.Entity("Diligent.WebAPI.Data.Entities.Insurer", b => | |||||
| { | |||||
| b.HasOne("Diligent.WebAPI.Data.Entities.InsuranceCompany", "InsuranceCompany") | |||||
| .WithMany() | |||||
| .HasForeignKey("InsuranceCompanyId") | |||||
| .OnDelete(DeleteBehavior.Cascade) | |||||
| .IsRequired(); | |||||
| b.Navigation("InsuranceCompany"); | |||||
| }); | |||||
| modelBuilder.Entity("Diligent.WebAPI.Data.Entities.WebhookSubscription", b => | |||||
| { | |||||
| b.HasOne("Diligent.WebAPI.Data.Entities.WebhookDefinition", "WebhookDefinition") | |||||
| .WithMany() | |||||
| .HasForeignKey("WebhookDefinitionId") | |||||
| .OnDelete(DeleteBehavior.Cascade) | |||||
| .IsRequired(); | |||||
| b.Navigation("WebhookDefinition"); | |||||
| }); | |||||
| #pragma warning restore 612, 618 | |||||
| } | |||||
| } | |||||
| } |
| global using Microsoft.EntityFrameworkCore; | |||||
| global using Microsoft.Extensions.Configuration; | |||||
| global using Microsoft.Extensions.DependencyInjection; | |||||
| global using System.ComponentModel.DataAnnotations; | |||||
| global using Diligent.WebAPI.Data.Entities; |
| namespace Diligent.WebAPI.Host.Attributes | |||||
| { | |||||
| [AttributeUsage(AttributeTargets.Method)] | |||||
| public class AuthorizeAttribute : Attribute, IAuthorizationFilter | |||||
| { | |||||
| public void OnAuthorization(AuthorizationFilterContext context) | |||||
| { | |||||
| User? user = (User?)context.HttpContext.Items["User"]; | |||||
| if (user == null) | |||||
| { | |||||
| // not logged in | |||||
| context.Result = new JsonResult(new { message = "Unauthorized" }) { StatusCode = StatusCodes.Status401Unauthorized }; | |||||
| } | |||||
| } | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Host.Controllers.V1 | |||||
| { | |||||
| [ApiVersion("1.0")] | |||||
| [ApiController] | |||||
| [Route("v{version:apiVersion}/insurance-companies")] | |||||
| public class InsuranceCompaniesController : ControllerBase | |||||
| { | |||||
| private readonly IInsuranceCompaniesService _insuranceCompaniesService; | |||||
| public InsuranceCompaniesController(IInsuranceCompaniesService insuranceCompaniesService) | |||||
| { | |||||
| _insuranceCompaniesService = insuranceCompaniesService; | |||||
| } | |||||
| /// <summary> | |||||
| /// Get list of all insurance companies | |||||
| /// </summary> | |||||
| [HttpGet] | |||||
| [ProducesResponseType(typeof(List<InsuranceCompanyViewDto>), StatusCodes.Status200OK)] | |||||
| [ProducesResponseType(typeof(ErrorResponseDto), StatusCodes.Status400BadRequest)] | |||||
| public async Task<IActionResult> GetInsuranceCompanies() | |||||
| { | |||||
| return Ok(await _insuranceCompaniesService.GetInsuranceCompanies()); | |||||
| } | |||||
| /// <summary> | |||||
| /// Get insurance company by id | |||||
| /// </summary> | |||||
| [HttpGet("{id}")] | |||||
| [ProducesResponseType(typeof(InsuranceCompanyViewDto), StatusCodes.Status200OK)] | |||||
| [ProducesResponseType(typeof(ErrorResponseDto), StatusCodes.Status400BadRequest)] | |||||
| [ProducesResponseType(StatusCodes.Status404NotFound)] | |||||
| public async Task<IActionResult> GetInsuranceCompany(long id) | |||||
| { | |||||
| return Ok(await _insuranceCompaniesService.GetInsuranceCompany(id)); | |||||
| } | |||||
| /// <summary> | |||||
| /// Create insurance company | |||||
| /// </summary> | |||||
| [HttpPost] | |||||
| [ProducesResponseType(typeof(InsuranceCompanyViewDto), StatusCodes.Status201Created)] | |||||
| [ProducesResponseType(typeof(ErrorResponseDto), StatusCodes.Status400BadRequest)] | |||||
| public async Task<IActionResult> CreateInsuranceCompany([FromBody] InsuranceCompanyCreateDto insuranceCompanyCreateDto) | |||||
| { | |||||
| await _insuranceCompaniesService.CreateInsuranceCompany(insuranceCompanyCreateDto); | |||||
| return StatusCode((int)HttpStatusCode.Created); | |||||
| } | |||||
| /// <summary> | |||||
| /// Update insurance company | |||||
| /// </summary> | |||||
| [HttpPut("{id}")] | |||||
| [ProducesResponseType(StatusCodes.Status200OK)] | |||||
| [ProducesResponseType(typeof(ErrorResponseDto), StatusCodes.Status400BadRequest)] | |||||
| [ProducesResponseType(StatusCodes.Status404NotFound)] | |||||
| public async Task<IActionResult> UpdateInsuranceCompany(long id, [FromBody] InsuranceCompanyUpdateDto insuranceCompanyUpdateDto) | |||||
| { | |||||
| await _insuranceCompaniesService.UpdateInsuranceCompany(id, insuranceCompanyUpdateDto); | |||||
| return Ok(); | |||||
| } | |||||
| /// <summary> | |||||
| /// Delete the specific insurance company | |||||
| /// </summary> | |||||
| [HttpDelete("{id}")] | |||||
| [ProducesResponseType(StatusCodes.Status204NoContent)] | |||||
| [ProducesResponseType(typeof(ErrorResponseDto), StatusCodes.Status400BadRequest)] | |||||
| [ProducesResponseType(StatusCodes.Status404NotFound)] | |||||
| public async Task<IActionResult> DeleteInsuranceCompany(long id) | |||||
| { | |||||
| await _insuranceCompaniesService.DeleteInsuranceCompany(id); | |||||
| return NoContent(); | |||||
| } | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Host.Controllers.V1 | |||||
| { | |||||
| [ApiVersion("1.0")] | |||||
| [ApiController] | |||||
| [Route("v{version:apiVersion}/insurance-policies")] | |||||
| public class InsurancePoliciesController : ControllerBase | |||||
| { | |||||
| private readonly IInsurancePoliciesService _insurancePoliciesService; | |||||
| private readonly IMapper _mapper; | |||||
| public InsurancePoliciesController(IInsurancePoliciesService insurancePoliciesService, | |||||
| IMapper mapper) | |||||
| { | |||||
| _insurancePoliciesService = insurancePoliciesService; | |||||
| _mapper = mapper; | |||||
| } | |||||
| /// <summary> | |||||
| /// Get list of all insurance policies | |||||
| /// </summary> | |||||
| [HttpGet] | |||||
| [ProducesResponseType(typeof(List<InsurancePolicyViewDto>), StatusCodes.Status200OK)] | |||||
| [ProducesResponseType(typeof(ErrorResponseDto), StatusCodes.Status400BadRequest)] | |||||
| public async Task<IActionResult> GetInsurancePolicies() | |||||
| { | |||||
| return Ok(await _insurancePoliciesService.GetInsurancePolicies()); | |||||
| } | |||||
| /// <summary> | |||||
| /// Get insurance policy by id | |||||
| /// </summary> | |||||
| [HttpGet("{id}")] | |||||
| [ProducesResponseType(typeof(InsurancePolicyViewDto), StatusCodes.Status200OK)] | |||||
| [ProducesResponseType(typeof(ErrorResponseDto), StatusCodes.Status400BadRequest)] | |||||
| [ProducesResponseType(StatusCodes.Status404NotFound)] | |||||
| public async Task<ActionResult<InsurancePolicyViewDto>> GetInsurancePolicy(long id) | |||||
| { | |||||
| return Ok(await _insurancePoliciesService.GetInsurancePolicy(id)); | |||||
| } | |||||
| /// <summary> | |||||
| /// Create insurance policy | |||||
| /// </summary> | |||||
| [HttpPost] | |||||
| [ProducesResponseType(StatusCodes.Status201Created)] | |||||
| [ProducesResponseType(typeof(ErrorResponseDto), StatusCodes.Status400BadRequest)] | |||||
| public async Task<ActionResult> CreateInsurancePolicy(InsurancePolicyCreateDto InsurancePolicyCreateDto) | |||||
| { | |||||
| await _insurancePoliciesService.CreateInsurancePolicy(InsurancePolicyCreateDto); | |||||
| return StatusCode((int)HttpStatusCode.Created); | |||||
| } | |||||
| /// <summary> | |||||
| /// Update insurance policy | |||||
| /// </summary> | |||||
| [HttpPut("{id}")] | |||||
| [ProducesResponseType(StatusCodes.Status200OK)] | |||||
| [ProducesResponseType(typeof(ErrorResponseDto), StatusCodes.Status400BadRequest)] | |||||
| [ProducesResponseType(StatusCodes.Status404NotFound)] | |||||
| public async Task<ActionResult> UpdateInsurancePolicy(long id, InsurancePolicyUpdateDto insurancePolicyUpdateDTO) | |||||
| { | |||||
| await _insurancePoliciesService.UpdateInsurancePolicy(id, insurancePolicyUpdateDTO); | |||||
| return Ok(); | |||||
| } | |||||
| /// <summary> | |||||
| /// Delete the specific insurance policy | |||||
| /// </summary> | |||||
| [HttpDelete("{id}")] | |||||
| [ProducesResponseType(StatusCodes.Status204NoContent)] | |||||
| [ProducesResponseType(typeof(ErrorResponseDto), StatusCodes.Status400BadRequest)] | |||||
| [ProducesResponseType(StatusCodes.Status404NotFound)] | |||||
| public async Task<ActionResult> DeleteInsurancePolicy(long id) | |||||
| { | |||||
| await _insurancePoliciesService.DeleteInsurancePolicy(id); | |||||
| return NoContent(); | |||||
| } | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Host.Controllers.V1 | |||||
| { | |||||
| [ApiVersion("1.0")] | |||||
| [ApiController] | |||||
| [Route("v{version:apiVersion}/insurers")] | |||||
| public class InsurersController : ControllerBase | |||||
| { | |||||
| private readonly IInsurersService _insurersService; | |||||
| public InsurersController(IInsurersService insurers) | |||||
| { | |||||
| _insurersService = insurers; | |||||
| } | |||||
| /// <summary> | |||||
| /// Get list of all insusers | |||||
| /// </summary> | |||||
| [HttpGet] | |||||
| [ProducesResponseType(typeof(List<InsurerViewDto>), StatusCodes.Status200OK)] | |||||
| [ProducesResponseType(typeof(ErrorResponseDto), StatusCodes.Status400BadRequest)] | |||||
| public async Task<IActionResult> GetInsurers() | |||||
| { | |||||
| return Ok(await _insurersService.GetInsurers()); | |||||
| } | |||||
| /// <summary> | |||||
| /// Get insurer by id | |||||
| /// </summary> | |||||
| [HttpGet("{id}")] | |||||
| [ProducesResponseType(typeof(InsurerViewDto), StatusCodes.Status200OK)] | |||||
| [ProducesResponseType(typeof(ErrorResponseDto), StatusCodes.Status400BadRequest)] | |||||
| [ProducesResponseType(StatusCodes.Status404NotFound)] | |||||
| public async Task<IActionResult> GetInsurer(long id) | |||||
| { | |||||
| return Ok(await _insurersService.GetInsurer(id)); | |||||
| } | |||||
| /// <summary> | |||||
| /// Create insurer | |||||
| /// </summary> | |||||
| [HttpPost] | |||||
| [ProducesResponseType(StatusCodes.Status201Created)] | |||||
| [ProducesResponseType(typeof(ErrorResponseDto), StatusCodes.Status400BadRequest)] | |||||
| public async Task<IActionResult> CreateInsurer([FromBody] InsurerCreateDto insurerCreateDto) | |||||
| { | |||||
| await _insurersService.CreateInsurer(insurerCreateDto); | |||||
| return StatusCode((int)HttpStatusCode.Created); | |||||
| } | |||||
| /// <summary> | |||||
| /// Update insurer | |||||
| /// </summary> | |||||
| [HttpPut("{id}")] | |||||
| [ProducesResponseType(StatusCodes.Status200OK)] | |||||
| [ProducesResponseType(typeof(ErrorResponseDto), StatusCodes.Status400BadRequest)] | |||||
| [ProducesResponseType(StatusCodes.Status404NotFound)] | |||||
| public async Task<IActionResult> UpdateInsurer(long id, [FromBody] InsurerUpdateDto insurerUpdateDto) | |||||
| { | |||||
| await _insurersService.UpdateInsurer(id, insurerUpdateDto); | |||||
| return Ok(); | |||||
| } | |||||
| /// <summary> | |||||
| /// Delete insurer | |||||
| /// </summary> | |||||
| [HttpDelete("{id}")] | |||||
| [ProducesResponseType(StatusCodes.Status204NoContent)] | |||||
| [ProducesResponseType(typeof(ErrorResponseDto), StatusCodes.Status400BadRequest)] | |||||
| [ProducesResponseType(StatusCodes.Status404NotFound)] | |||||
| public async Task<IActionResult> DeleteInsurer(long insurerId) | |||||
| { | |||||
| await _insurersService.DeleteInsurerAsync(insurerId); | |||||
| return NoContent(); | |||||
| } | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Host.Controllers.V1 | |||||
| { | |||||
| [ApiVersion("1.0")] | |||||
| [Route("v{version:apiVersion}/users")] | |||||
| [ApiController] | |||||
| public class UsersController : ControllerBase | |||||
| { | |||||
| private readonly IUserService _userService; | |||||
| public UsersController(IUserService userService) | |||||
| { | |||||
| _userService = userService; | |||||
| } | |||||
| [Authorize] | |||||
| [HttpGet] | |||||
| public IActionResult GetAll() | |||||
| { | |||||
| return Ok("Hello from protected route"); | |||||
| } | |||||
| [HttpPost("authenticate")] | |||||
| public IActionResult Authenticate([FromBody] AuthenticateRequestDto model) | |||||
| { | |||||
| var response = _userService.Authenticate(model); | |||||
| if (response == null) | |||||
| return BadRequest(new { message = "Username or password is incorrect" }); | |||||
| return Ok(response); | |||||
| } | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Host.Controllers.V1 | |||||
| { | |||||
| [ApiVersion("1.0")] | |||||
| [ApiController] | |||||
| [Route("v{version:apiVersion}/webhooks")] | |||||
| public class WebhooksController : ControllerBase | |||||
| { | |||||
| private readonly IWebhookSubscriptionService _webhookSubscriptionService; | |||||
| private readonly IWebhookDefinitionService _webhookDefinitionService; | |||||
| public WebhooksController( | |||||
| IWebhookSubscriptionService subscriptionService, | |||||
| IWebhookDefinitionService definitionsService) | |||||
| { | |||||
| _webhookSubscriptionService = subscriptionService; | |||||
| _webhookDefinitionService = definitionsService; | |||||
| } | |||||
| /// <summary> | |||||
| /// Create webhook subscription | |||||
| /// </summary> | |||||
| [HttpPost] | |||||
| [ProducesResponseType(StatusCodes.Status201Created)] | |||||
| [ProducesResponseType(typeof(ErrorResponseDto), StatusCodes.Status400BadRequest)] | |||||
| public async Task<IActionResult> Post([FromBody] WebhookSubscriptionCreateDto dto) | |||||
| { | |||||
| await _webhookSubscriptionService.CreateWebhookSubscription(dto); | |||||
| return StatusCode(StatusCodes.Status201Created); | |||||
| } | |||||
| /// <summary> | |||||
| /// Get all webhook definitions | |||||
| /// </summary> | |||||
| [HttpGet("definitions")] | |||||
| [ProducesResponseType(typeof(List<WebhookDefinitionViewDto>), StatusCodes.Status200OK)] | |||||
| [ProducesResponseType(typeof(ErrorResponseDto), StatusCodes.Status400BadRequest)] | |||||
| public async Task<IActionResult> GetDefinitions() | |||||
| { | |||||
| return Ok(await _webhookDefinitionService.GetAll()); | |||||
| } | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Host.Controllers.V2 | |||||
| { | |||||
| [ApiVersion("2.0")] | |||||
| [ApiController] | |||||
| [Route("v{version:apiVersion}/insurance-companies")] | |||||
| public class InsuranceCompaniesController : ControllerBase | |||||
| { | |||||
| private readonly IInsuranceCompaniesService insuranceCompaniesService; | |||||
| public InsuranceCompaniesController(IInsuranceCompaniesService insuranceCompaniesService) | |||||
| { | |||||
| this.insuranceCompaniesService = insuranceCompaniesService; | |||||
| } | |||||
| /// <summary> | |||||
| /// Get list of all insurance companies | |||||
| /// </summary> | |||||
| [HttpGet] | |||||
| [ProducesResponseType(typeof(List<InsuranceCompanyViewDto>), StatusCodes.Status200OK)] | |||||
| [ProducesResponseType(typeof(ErrorResponseDto), StatusCodes.Status400BadRequest)] | |||||
| public async Task<IActionResult> GetInsuranceCompanies() | |||||
| { | |||||
| return Ok(await insuranceCompaniesService.GetInsuranceCompanies()); | |||||
| } | |||||
| /// <summary> | |||||
| /// Get insurance company by id | |||||
| /// </summary> | |||||
| [HttpGet("{id}")] | |||||
| [ProducesResponseType(typeof(InsuranceCompanyViewDto), StatusCodes.Status200OK)] | |||||
| [ProducesResponseType(typeof(ErrorResponseDto), StatusCodes.Status400BadRequest)] | |||||
| [ProducesResponseType(StatusCodes.Status404NotFound)] | |||||
| public async Task<IActionResult> GetInsuranceCompany(long id) | |||||
| { | |||||
| return Ok(await insuranceCompaniesService.GetInsuranceCompany(id)); | |||||
| } | |||||
| /// <summary> | |||||
| /// Create insurance company | |||||
| /// </summary> | |||||
| [HttpPost] | |||||
| [ProducesResponseType(typeof(InsuranceCompanyViewDto), StatusCodes.Status201Created)] | |||||
| [ProducesResponseType(typeof(ErrorResponseDto), StatusCodes.Status400BadRequest)] | |||||
| public async Task<IActionResult> CreateInsuranceCompany([FromBody] InsuranceCompanyCreateDto insuranceCompanyCreateDto) | |||||
| { | |||||
| await insuranceCompaniesService.CreateInsuranceCompany(insuranceCompanyCreateDto); | |||||
| return StatusCode((int)HttpStatusCode.Created); | |||||
| } | |||||
| /// <summary> | |||||
| /// Update insurance company | |||||
| /// </summary> | |||||
| [HttpPut("{id}")] | |||||
| [ProducesResponseType(StatusCodes.Status200OK)] | |||||
| [ProducesResponseType(typeof(ErrorResponseDto), StatusCodes.Status400BadRequest)] | |||||
| [ProducesResponseType(StatusCodes.Status404NotFound)] | |||||
| public async Task<IActionResult> UpdateInsuranceCompany(long id, [FromBody] InsuranceCompanyUpdateDto insuranceCompanyUpdateDto) | |||||
| { | |||||
| await insuranceCompaniesService.UpdateInsuranceCompany(id, insuranceCompanyUpdateDto); | |||||
| return Ok(); | |||||
| } | |||||
| /// <summary> | |||||
| /// Delete the specific insurance company | |||||
| /// </summary> | |||||
| [HttpDelete("{id}")] | |||||
| [ProducesResponseType(StatusCodes.Status204NoContent)] | |||||
| [ProducesResponseType(typeof(ErrorResponseDto), StatusCodes.Status400BadRequest)] | |||||
| [ProducesResponseType(StatusCodes.Status404NotFound)] | |||||
| public async Task<IActionResult> DeleteInsuranceCompany(long id) | |||||
| { | |||||
| await insuranceCompaniesService.DeleteInsuranceCompany(id); | |||||
| return NoContent(); | |||||
| } | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Host.Controllers.V2 | |||||
| { | |||||
| [ApiVersion("2.0")] | |||||
| [ApiController] | |||||
| [Route("v{version:apiVersion}/insurance-policies")] | |||||
| public class InsurancePoliciesController : ControllerBase | |||||
| { | |||||
| private readonly IInsurancePoliciesService _insurancePoliciesService; | |||||
| private readonly IMapper _mapper; | |||||
| public InsurancePoliciesController(IInsurancePoliciesService insurancePoliciesService, | |||||
| IMapper mapper) | |||||
| { | |||||
| _insurancePoliciesService = insurancePoliciesService; | |||||
| _mapper = mapper; | |||||
| } | |||||
| /// <summary> | |||||
| /// Get list of all insurance policies | |||||
| /// </summary> | |||||
| [HttpGet] | |||||
| [ProducesResponseType(typeof(List<InsurancePolicyViewDto>), StatusCodes.Status200OK)] | |||||
| [ProducesResponseType(typeof(ErrorResponseDto), StatusCodes.Status400BadRequest)] | |||||
| public async Task<IActionResult> GetInsurancePolicies() | |||||
| { | |||||
| return Ok(await _insurancePoliciesService.GetInsurancePolicies()); | |||||
| } | |||||
| /// <summary> | |||||
| /// Get insurance policy by id | |||||
| /// </summary> | |||||
| [HttpGet("{id}")] | |||||
| [ProducesResponseType(typeof(InsurancePolicyViewDto), StatusCodes.Status200OK)] | |||||
| [ProducesResponseType(typeof(ErrorResponseDto), StatusCodes.Status400BadRequest)] | |||||
| [ProducesResponseType(StatusCodes.Status404NotFound)] | |||||
| public async Task<ActionResult<InsurancePolicyViewDto>> GetInsurancePolicy(long id) | |||||
| { | |||||
| return Ok(await _insurancePoliciesService.GetInsurancePolicy(id)); | |||||
| } | |||||
| /// <summary> | |||||
| /// Create insurance policy | |||||
| /// </summary> | |||||
| [HttpPost] | |||||
| [ProducesResponseType(StatusCodes.Status201Created)] | |||||
| [ProducesResponseType(typeof(ErrorResponseDto), StatusCodes.Status400BadRequest)] | |||||
| public async Task<ActionResult> CreateInsurancePolicy(InsurancePolicyCreateDto InsurancePolicyCreateDto) | |||||
| { | |||||
| await _insurancePoliciesService.CreateInsurancePolicy(InsurancePolicyCreateDto); | |||||
| return StatusCode((int)HttpStatusCode.Created); | |||||
| } | |||||
| /// <summary> | |||||
| /// Update insurance policy | |||||
| /// </summary> | |||||
| [HttpPut("{id}")] | |||||
| [ProducesResponseType(StatusCodes.Status200OK)] | |||||
| [ProducesResponseType(typeof(ErrorResponseDto), StatusCodes.Status400BadRequest)] | |||||
| [ProducesResponseType(StatusCodes.Status404NotFound)] | |||||
| public async Task<ActionResult> UpdateInsurancePolicy(long id, InsurancePolicyUpdateDto insurancePolicyUpdateDTO) | |||||
| { | |||||
| await _insurancePoliciesService.UpdateInsurancePolicy(id, insurancePolicyUpdateDTO); | |||||
| return Ok(); | |||||
| } | |||||
| /// <summary> | |||||
| /// Delete the specific insurance policy | |||||
| /// </summary> | |||||
| [HttpDelete("{id}")] | |||||
| [ProducesResponseType(StatusCodes.Status204NoContent)] | |||||
| [ProducesResponseType(typeof(ErrorResponseDto), StatusCodes.Status400BadRequest)] | |||||
| [ProducesResponseType(StatusCodes.Status404NotFound)] | |||||
| public async Task<ActionResult> DeleteInsurancePolicy(long id) | |||||
| { | |||||
| await _insurancePoliciesService.DeleteInsurancePolicy(id); | |||||
| return NoContent(); | |||||
| } | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Host.Controllers.V2 | |||||
| { | |||||
| [ApiVersion("2.0")] | |||||
| [ApiController] | |||||
| [Route("v{version:apiVersion}/insurers")] | |||||
| public class InsurersController : ControllerBase | |||||
| { | |||||
| private readonly IInsurersService _insurersService; | |||||
| public InsurersController(IInsurersService insurers) | |||||
| { | |||||
| _insurersService = insurers; | |||||
| } | |||||
| /// <summary> | |||||
| /// Get list of all insusers | |||||
| /// </summary> | |||||
| [HttpGet] | |||||
| [ProducesResponseType(typeof(List<InsurerViewDto>), StatusCodes.Status200OK)] | |||||
| [ProducesResponseType(typeof(ErrorResponseDto), StatusCodes.Status400BadRequest)] | |||||
| public async Task<IActionResult> GetInsurers() | |||||
| { | |||||
| return Ok(await _insurersService.GetInsurers()); | |||||
| } | |||||
| /// <summary> | |||||
| /// Get insurer by id | |||||
| /// </summary> | |||||
| [HttpGet("{id}")] | |||||
| [ProducesResponseType(typeof(InsurerViewDto), StatusCodes.Status200OK)] | |||||
| [ProducesResponseType(typeof(ErrorResponseDto), StatusCodes.Status400BadRequest)] | |||||
| [ProducesResponseType(StatusCodes.Status404NotFound)] | |||||
| public async Task<IActionResult> GetInsurer(long id) | |||||
| { | |||||
| return Ok(await _insurersService.GetInsurer(id)); | |||||
| } | |||||
| /// <summary> | |||||
| /// Create insurer | |||||
| /// </summary> | |||||
| [HttpPost] | |||||
| [ProducesResponseType(StatusCodes.Status201Created)] | |||||
| [ProducesResponseType(typeof(ErrorResponseDto), StatusCodes.Status400BadRequest)] | |||||
| public async Task<IActionResult> CreateInsurer([FromBody] InsurerCreateDto insurerCreateDto) | |||||
| { | |||||
| await _insurersService.CreateInsurer(insurerCreateDto); | |||||
| return StatusCode((int)HttpStatusCode.Created); | |||||
| } | |||||
| /// <summary> | |||||
| /// Update insurer | |||||
| /// </summary> | |||||
| [HttpPut("{id}")] | |||||
| [ProducesResponseType(StatusCodes.Status200OK)] | |||||
| [ProducesResponseType(typeof(ErrorResponseDto), StatusCodes.Status400BadRequest)] | |||||
| [ProducesResponseType(StatusCodes.Status404NotFound)] | |||||
| public async Task<IActionResult> UpdateInsurer(long id, [FromBody] InsurerUpdateDto insurerUpdateDto) | |||||
| { | |||||
| await _insurersService.UpdateInsurer(id, insurerUpdateDto); | |||||
| return Ok(); | |||||
| } | |||||
| /// <summary> | |||||
| /// Delete insurer | |||||
| /// </summary> | |||||
| [HttpDelete("{id}")] | |||||
| [ProducesResponseType(StatusCodes.Status204NoContent)] | |||||
| [ProducesResponseType(typeof(ErrorResponseDto), StatusCodes.Status400BadRequest)] | |||||
| [ProducesResponseType(StatusCodes.Status404NotFound)] | |||||
| public async Task<IActionResult> DeleteInsurer(long insurerId) | |||||
| { | |||||
| await _insurersService.DeleteInsurerAsync(insurerId); | |||||
| return NoContent(); | |||||
| } | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Host.Controllers.V2 | |||||
| { | |||||
| [ApiVersion("2.0")] | |||||
| [Route("v{version:apiVersion}/[controller]")] | |||||
| [ApiController] | |||||
| public class UsersController : ControllerBase | |||||
| { | |||||
| private readonly IUserService _userService; | |||||
| public UsersController(IUserService userService) | |||||
| { | |||||
| _userService = userService; | |||||
| } | |||||
| [Authorize] | |||||
| [HttpGet] | |||||
| public IActionResult GetAll() | |||||
| { | |||||
| return Ok("Hello from protected route"); | |||||
| } | |||||
| [HttpPost("authenticate")] | |||||
| public IActionResult Authenticate([FromBody] AuthenticateRequestDto model) | |||||
| { | |||||
| var response = _userService.Authenticate(model); | |||||
| if (response == null) | |||||
| return BadRequest(new { message = "Username or password is incorrect" }); | |||||
| return Ok(response); | |||||
| } | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Host.Controllers.V2 | |||||
| { | |||||
| [ApiVersion("2.0")] | |||||
| [ApiController] | |||||
| [Route("v{version:apiVersion}/webhooks")] | |||||
| public class WebhooksController : ControllerBase | |||||
| { | |||||
| private readonly IWebhookSubscriptionService _webhookSubscriptionService; | |||||
| private readonly IWebhookDefinitionService _webhookDefinitionService; | |||||
| public WebhooksController( | |||||
| IWebhookSubscriptionService subscriptionService, | |||||
| IWebhookDefinitionService definitionsService) | |||||
| { | |||||
| _webhookSubscriptionService = subscriptionService; | |||||
| _webhookDefinitionService = definitionsService; | |||||
| } | |||||
| /// <summary> | |||||
| /// Create webhook subscription | |||||
| /// </summary> | |||||
| [HttpPost] | |||||
| [ProducesResponseType(StatusCodes.Status201Created)] | |||||
| [ProducesResponseType(typeof(ErrorResponseDto), StatusCodes.Status400BadRequest)] | |||||
| public async Task<IActionResult> Post([FromBody] WebhookSubscriptionCreateDto dto) | |||||
| { | |||||
| await _webhookSubscriptionService.CreateWebhookSubscription(dto); | |||||
| return StatusCode(StatusCodes.Status201Created); | |||||
| } | |||||
| /// <summary> | |||||
| /// Get all webhook definitions | |||||
| /// </summary> | |||||
| [HttpGet("definitions")] | |||||
| [ProducesResponseType(typeof(List<WebhookDefinitionViewDto>), StatusCodes.Status200OK)] | |||||
| [ProducesResponseType(typeof(ErrorResponseDto), StatusCodes.Status400BadRequest)] | |||||
| public async Task<IActionResult> GetDefinitions() | |||||
| { | |||||
| return Ok(await _webhookDefinitionService.GetAll()); | |||||
| } | |||||
| } | |||||
| } |
| <Project Sdk="Microsoft.NET.Sdk.Web"> | |||||
| <PropertyGroup> | |||||
| <TargetFramework>net6.0</TargetFramework> | |||||
| <Nullable>enable</Nullable> | |||||
| <ImplicitUsings>enable</ImplicitUsings> | |||||
| </PropertyGroup> | |||||
| <PropertyGroup> | |||||
| <GenerateDocumentationFile>true</GenerateDocumentationFile> | |||||
| </PropertyGroup> | |||||
| <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> | |||||
| <NoWarn>1701;1702;1591</NoWarn> | |||||
| </PropertyGroup> | |||||
| <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'"> | |||||
| <NoWarn>1701;1702;1591</NoWarn> | |||||
| </PropertyGroup> | |||||
| <ItemGroup> | |||||
| <None Include="..\.editorconfig" Link=".editorconfig" /> | |||||
| </ItemGroup> | |||||
| <ItemGroup> | |||||
| <PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="11.0.0" /> | |||||
| <PackageReference Include="Microsoft.AspNet.WebApi.Core" Version="5.2.9" /> | |||||
| <PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning" Version="5.0.0" /> | |||||
| <PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer" Version="5.0.0" /> | |||||
| <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.3"> | |||||
| <PrivateAssets>all</PrivateAssets> | |||||
| <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | |||||
| </PackageReference> | |||||
| <PackageReference Include="Swashbuckle.AspNetCore" Version="6.3.2" /> | |||||
| <PackageReference Include="Serilog.AspNetCore" Version="5.0.0" /> | |||||
| <PackageReference Include="Serilog.Sinks.Seq" Version="5.1.1" /> | |||||
| <PackageReference Include="SerilogTimings" Version="2.3.0" /> | |||||
| </ItemGroup> | |||||
| <ItemGroup> | |||||
| <ProjectReference Include="..\Diligent.WebAPI.Business\Diligent.WebAPI.Business.csproj" /> | |||||
| <ProjectReference Include="..\Diligent.WebAPI.Contracts\Diligent.WebAPI.Contracts.csproj" /> | |||||
| <ProjectReference Include="..\Diligent.WebAPI.Data\Diligent.WebAPI.Data.csproj" /> | |||||
| </ItemGroup> | |||||
| </Project> |
| <?xml version="1.0" encoding="utf-8"?> | |||||
| <Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | |||||
| <PropertyGroup> | |||||
| <Controller_SelectedScaffolderID>ApiControllerWithActionsScaffolder</Controller_SelectedScaffolderID> | |||||
| <Controller_SelectedScaffolderCategoryPath>root/Common/Api</Controller_SelectedScaffolderCategoryPath> | |||||
| <ActiveDebugProfile>IIS Express</ActiveDebugProfile> | |||||
| </PropertyGroup> | |||||
| <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> | |||||
| <DebuggerFlavor>ProjectDebugger</DebuggerFlavor> | |||||
| </PropertyGroup> | |||||
| </Project> |
| namespace Diligent.WebAPI.Host.Extensions | |||||
| { | |||||
| public static class AuthConfigurationExtension | |||||
| { | |||||
| public static void ConfigureAuth(this WebApplicationBuilder builder) | |||||
| { | |||||
| builder.Services.Configure<AuthorizationSettings>(builder.Configuration.GetSection("Authorization")); | |||||
| builder.Services.AddScoped<IUserService, UserService>(); | |||||
| } | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Host.Extensions | |||||
| { | |||||
| public static class BusinessConfigurationExtension | |||||
| { | |||||
| /// <summary> | |||||
| /// Services configuration | |||||
| /// </summary> | |||||
| public static void ConfigureBusiness(this WebApplicationBuilder builder) | |||||
| { | |||||
| IServiceCollection services = builder.Services; | |||||
| services.AddAutoMapper(typeof(CompanyMappingProfile)); | |||||
| services.AddAutoMapper(typeof(WebhookMappingProfile)); | |||||
| services.AddAutoMapper(typeof(InsurerMappingProfile)); | |||||
| services.AddScoped<IInsurersService, InsurersService>(); | |||||
| services.AddScoped<IInsuranceCompaniesService, InsuranceCompaniesService>(); | |||||
| services.AddScoped<IInsurancePoliciesService, InsurancePoliciesService>(); | |||||
| services.AddScoped<IWebhookSubscriptionService, WebhookSubscriptionService>(); | |||||
| services.AddScoped<IWebhookDefinitionService, WebhookDefinitionService>(); | |||||
| services.AddScoped<IWebhookPublisherService, WebhookPublisherService>(); | |||||
| } | |||||
| /// <summary> | |||||
| /// App configuration | |||||
| /// </summary> | |||||
| public static void ConfigureBusiness(this WebApplication app) | |||||
| { | |||||
| // | |||||
| } | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Host.Extensions | |||||
| { | |||||
| public static class CorrelationIdExtension | |||||
| { | |||||
| public static IApplicationBuilder UseCorrelationId(this IApplicationBuilder app) | |||||
| { | |||||
| return app.UseMiddleware<CorrelationMiddleware>(); | |||||
| } | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Host.Extensions; | |||||
| public static class DataConfigurationExtension | |||||
| { | |||||
| /// <summary> | |||||
| /// Services configuration | |||||
| /// </summary> | |||||
| public static void ConfigureData(this WebApplicationBuilder builder) | |||||
| { | |||||
| IServiceCollection services = builder.Services; | |||||
| services.ConfigureData(builder.Configuration); | |||||
| } | |||||
| /// <summary> | |||||
| /// App configuration | |||||
| /// </summary> | |||||
| public static void ConfigureData(this WebApplication app) | |||||
| { | |||||
| // | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Host.Extensions | |||||
| { | |||||
| public static class HostConfigurationExtension | |||||
| { | |||||
| /// <summary> | |||||
| /// Services configuration | |||||
| /// </summary> | |||||
| public static void ConfigureHost(this WebApplicationBuilder builder) | |||||
| { | |||||
| builder.ConfigureAuth(); | |||||
| builder.ConfigureValidationMiddleware(); | |||||
| builder.ConfigureSwagger(); | |||||
| IServiceCollection services = builder.Services; | |||||
| services.AddControllers(); | |||||
| services.AddEndpointsApiExplorer(); | |||||
| } | |||||
| /// <summary> | |||||
| /// App configuration | |||||
| /// </summary> | |||||
| public static void ConfigureHost(this WebApplication app) | |||||
| { | |||||
| app.UseCorrelationId(); | |||||
| app.MapControllers(); | |||||
| app.SetupData(); | |||||
| // custom jwt auth middleware | |||||
| app.UseMiddleware<JwtMiddleware>(); | |||||
| app.UseDiligExceptionHandler(); | |||||
| app.ConfigureSwagger(); | |||||
| } | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Host.Extensions | |||||
| { | |||||
| public static class ModelValidationMIddlewareExtension | |||||
| { | |||||
| public static void ConfigureValidationMiddleware(this WebApplicationBuilder builder) | |||||
| { | |||||
| var services = builder.Services; | |||||
| // Override default model validation middleware. | |||||
| services.Configure<ApiBehaviorOptions>(options => | |||||
| { | |||||
| options.SuppressModelStateInvalidFilter = true; | |||||
| }); | |||||
| // Register custom validation middleware | |||||
| services.AddMvcCore(options => | |||||
| { | |||||
| options.Filters.Add(typeof(ModelValidationMiddleware)); | |||||
| }) | |||||
| .AddDataAnnotations(); | |||||
| } | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Host.Extensions | |||||
| { | |||||
| public static class SwaggerConfigurationExtension | |||||
| { | |||||
| public static void ConfigureSwagger(this WebApplicationBuilder builder) | |||||
| { | |||||
| IServiceCollection services = builder.Services; | |||||
| services.AddVersionedApiExplorer(setup => | |||||
| { | |||||
| setup.GroupNameFormat = "'v'VVV"; | |||||
| setup.SubstituteApiVersionInUrl = true; | |||||
| }); | |||||
| services.AddSwaggerGen(options => | |||||
| { | |||||
| var xmlFilename = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; | |||||
| options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFilename)); | |||||
| } | |||||
| ); | |||||
| services.ConfigureOptions<SwaggerConfigureOptions>(); | |||||
| services.AddApiVersioning(options => | |||||
| { | |||||
| options.AssumeDefaultVersionWhenUnspecified = true; | |||||
| options.ReportApiVersions = true; | |||||
| options.DefaultApiVersion = new ApiVersion(1, 0); | |||||
| options.ApiVersionReader = new UrlSegmentApiVersionReader(); | |||||
| }); | |||||
| } | |||||
| public static void ConfigureSwagger(this WebApplication app) | |||||
| { | |||||
| if (app.Environment.IsDevelopment()) | |||||
| { | |||||
| app.UseSwagger(); | |||||
| app.UseSwaggerUI(options => | |||||
| { | |||||
| options.SwaggerEndpoint("/swagger/v1/swagger.json", "v1"); | |||||
| options.SwaggerEndpoint("/swagger/v2/swagger.json", "v2"); | |||||
| options.RoutePrefix = string.Empty; | |||||
| }); | |||||
| } | |||||
| } | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Host.Extensions; | |||||
| public static class WebAppExtension | |||||
| { | |||||
| public static void SetupData(this WebApplication app) | |||||
| { | |||||
| IServiceScope serviceScope = app.Services.CreateScope(); | |||||
| serviceScope.SetupData(); | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Host.Middlewares | |||||
| { | |||||
| public class CorrelationMiddleware | |||||
| { | |||||
| private const string DefaultHeader = "X-Correlation-ID"; | |||||
| private readonly RequestDelegate next; | |||||
| private readonly ILogger<CorrelationMiddleware> logger; | |||||
| public CorrelationMiddleware(RequestDelegate next, ILogger<CorrelationMiddleware> logger) => (this.next,this.logger) = (next,logger); | |||||
| public async Task Invoke(HttpContext context) | |||||
| { | |||||
| if (!context.Request.Headers.TryGetValue(DefaultHeader, out var correlation)) | |||||
| { | |||||
| correlation = Guid.NewGuid().ToString(); | |||||
| } | |||||
| context.Response.OnStarting(() => | |||||
| { | |||||
| if (!context.Response.Headers.ContainsKey(DefaultHeader)) | |||||
| { | |||||
| context.Response.Headers.Add(DefaultHeader, correlation); | |||||
| } | |||||
| return Task.CompletedTask; | |||||
| }); | |||||
| using (logger.BeginScope(new Dictionary<string, object> | |||||
| { | |||||
| ["CorrelationId"] = correlation | |||||
| })) | |||||
| { | |||||
| context.Items.Add(DefaultHeader, correlation); | |||||
| await next(context); | |||||
| } | |||||
| } | |||||
| } | |||||
| } |
| using Diligent.WebAPI.Contracts.Exceptions; | |||||
| using Diligent.WebAPI.Contracts.Models; | |||||
| using Microsoft.AspNetCore.Mvc; | |||||
| using Microsoft.Extensions.Options; | |||||
| using Newtonsoft.Json; | |||||
| using Newtonsoft.Json.Serialization; | |||||
| using System.Diagnostics; | |||||
| using System.Net; | |||||
| using System.Runtime.Serialization; | |||||
| namespace Diligent.WebAPI.Host.Middlewares | |||||
| { | |||||
| public class DiligBadRequestException : Exception | |||||
| { | |||||
| public const string ExceptionMessage = "Bad request from custom middleware"; | |||||
| public const string ExceptionCode = "DiligBadRequestException"; | |||||
| public const HttpStatusCode HttpResponseCode = HttpStatusCode.BadRequest; | |||||
| public DiligBadRequestException() : base(ExceptionMessage) { } | |||||
| public DiligBadRequestException(string message) : base(message) { } | |||||
| public DiligBadRequestException(string message, Exception innerException) : base(message, innerException) { } | |||||
| public DiligBadRequestException(SerializationInfo info, StreamingContext context) : base(info, context) { } | |||||
| } | |||||
| public class DiligExceptionMiddleware | |||||
| { | |||||
| private readonly RequestDelegate _next; | |||||
| private readonly ILogger<DiligExceptionMiddleware> _logger; | |||||
| private readonly IWebHostEnvironment _env; | |||||
| private readonly ApiBehaviorOptions _options; | |||||
| public DiligExceptionMiddleware(RequestDelegate next, ILogger<DiligExceptionMiddleware> logger, IWebHostEnvironment env, IOptions<ApiBehaviorOptions> options) | |||||
| => (_next, _logger, _env, _options) = (next, logger, env, options.Value); | |||||
| public async Task InvokeAsync(HttpContext httpContext) | |||||
| { | |||||
| try | |||||
| { | |||||
| await _next(httpContext); | |||||
| } | |||||
| // Some custom Exceptions | |||||
| catch (EntityNotFoundException ex) | |||||
| { | |||||
| _logger.LogError(ex, DiligBadRequestException.ExceptionMessage); | |||||
| await HandleExceptionAsync(httpContext, ex, DiligBadRequestException.ExceptionMessage, HttpStatusCode.NotFound); | |||||
| } | |||||
| catch (Exception ex) | |||||
| { | |||||
| // Better solution is to use switch statement | |||||
| if(HasInternalExceptionOfType<DiligBadRequestException>(ex)) | |||||
| { | |||||
| _logger.LogError(ex, DiligBadRequestException.ExceptionMessage); | |||||
| await HandleExceptionAsync(httpContext, ex, DiligBadRequestException.ExceptionMessage, DiligBadRequestException.HttpResponseCode); | |||||
| } | |||||
| else | |||||
| { | |||||
| await HandleSomethingWentWrongAsync(httpContext, ex); | |||||
| } | |||||
| } | |||||
| } | |||||
| private async Task HandleSomethingWentWrongAsync(HttpContext httpContext, Exception ex) | |||||
| { | |||||
| _logger.LogError(ex, "Something went wrong"); | |||||
| await HandleExceptionAsync(httpContext, ex); | |||||
| } | |||||
| private bool HasInternalExceptionOfType<T>(Exception e) | |||||
| { | |||||
| if(e.InnerException != null) | |||||
| { | |||||
| return e is T || HasInternalExceptionOfType<T>(e.InnerException); | |||||
| } | |||||
| return e is T; | |||||
| } | |||||
| private Task HandleExceptionAsync(HttpContext context, Exception exception, string? message = null, HttpStatusCode? responseCode = null) | |||||
| { | |||||
| context.Response.ContentType = "application/json"; | |||||
| context.Response.StatusCode = (int)(responseCode ?? HttpStatusCode.InternalServerError); | |||||
| string type = null; | |||||
| if (_options.ClientErrorMapping.TryGetValue(context.Response.StatusCode, out var clientErrorData)) | |||||
| { | |||||
| type = clientErrorData.Link; | |||||
| } | |||||
| var errorTitle = message ?? (_env.IsDevelopment() ? exception.Message : "Internal server error"); | |||||
| var errorMessage = _env.IsDevelopment() ? exception.StackTrace : "Something went wrong" ; | |||||
| var serializerSettings = new JsonSerializerSettings | |||||
| { | |||||
| ContractResolver = new CamelCasePropertyNamesContractResolver() | |||||
| }; | |||||
| var resultError = new ResultError(errorTitle); | |||||
| var httpResultError = new HttpResultError() | |||||
| { | |||||
| ErrorMessage = errorMessage, | |||||
| ErrorCode = responseCode ?? HttpStatusCode.InternalServerError | |||||
| }; | |||||
| resultError.AddCustomError(httpResultError); | |||||
| var responseString = JsonConvert.SerializeObject( | |||||
| new BaseResult<Exception> | |||||
| { | |||||
| // Type = type, | |||||
| // TraceId = Activity.Current?.Id ?? context?.TraceIdentifier, | |||||
| IsSuccess = false, | |||||
| Errors = { resultError } | |||||
| }, serializerSettings); | |||||
| return context.Response.WriteAsync(responseString); | |||||
| } | |||||
| } | |||||
| public static class DiligExceptionMiddlewareExtensions | |||||
| { | |||||
| public static IApplicationBuilder UseDiligExceptionHandler(this IApplicationBuilder app) | |||||
| { | |||||
| return app.UseMiddleware<DiligExceptionMiddleware>(); | |||||
| } | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Host.Middlewares | |||||
| { | |||||
| public class JwtMiddleware | |||||
| { | |||||
| private readonly RequestDelegate _next; | |||||
| private readonly AuthorizationSettings _authSettings; | |||||
| public JwtMiddleware(RequestDelegate next, IOptions<AuthorizationSettings> authSettings) | |||||
| { | |||||
| _next = next; | |||||
| _authSettings = authSettings.Value; | |||||
| } | |||||
| public async Task Invoke(HttpContext context, IUserService userService) | |||||
| { | |||||
| var token = context.Request.Headers["Authorization"].FirstOrDefault()?.Split(" ").Last(); | |||||
| if (token != null) | |||||
| AttachUserToContext(context, userService, token); | |||||
| await _next(context); | |||||
| } | |||||
| private void AttachUserToContext(HttpContext context, IUserService userService, string token) | |||||
| { | |||||
| try | |||||
| { | |||||
| var tokenHandler = new JwtSecurityTokenHandler(); | |||||
| var key = Encoding.ASCII.GetBytes(_authSettings.Secret); | |||||
| tokenHandler.ValidateToken(token, new TokenValidationParameters | |||||
| { | |||||
| ValidateIssuerSigningKey = true, | |||||
| IssuerSigningKey = new SymmetricSecurityKey(key), | |||||
| ValidateIssuer = false, | |||||
| ValidateAudience = false, | |||||
| // set clockskew to zero so tokens expire exactly at token expiration time (instead of 5 minutes later) | |||||
| ClockSkew = TimeSpan.Zero | |||||
| }, out SecurityToken validatedToken); | |||||
| var jwtToken = (JwtSecurityToken)validatedToken; | |||||
| var userId = int.Parse(jwtToken.Claims.First(x => x.Type == "id").Value); | |||||
| // attach user to context on successful jwt validation | |||||
| context.Items["User"] = userService.GetById(userId); | |||||
| } | |||||
| catch | |||||
| { | |||||
| // do nothing if jwt validation fails | |||||
| // user is not attached to context so request won't have access to secure routes | |||||
| } | |||||
| } | |||||
| } | |||||
| } |
| using Diligent.WebAPI.Contracts.DTOs.Error; | |||||
| using Microsoft.AspNetCore.Mvc; | |||||
| using Microsoft.AspNetCore.Mvc.Filters; | |||||
| namespace Diligent.WebAPI.Host.Middlewares | |||||
| { | |||||
| public class ModelValidationMiddleware : IActionFilter | |||||
| { | |||||
| public void OnActionExecuted(ActionExecutedContext context) { } | |||||
| public void OnActionExecuting(ActionExecutingContext context) | |||||
| { | |||||
| if (!context.ModelState.IsValid) | |||||
| { | |||||
| // create response model | |||||
| var response = new ErrorResponseDto("Invalid model") | |||||
| { | |||||
| // get model validation errors from ModelState | |||||
| ValidationItems = context.ModelState | |||||
| .Where(x => x.Value != null && x.Value.Errors.Count > 0) | |||||
| .Select(x => new ValidationItemDto { Key = x.Key, Value = x.Value?.Errors.Select(e => e.ErrorMessage).First() }) | |||||
| .ToList() | |||||
| }; | |||||
| // return validation model | |||||
| context.Result = new BadRequestObjectResult(response); | |||||
| } | |||||
| } | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Host.Options | |||||
| { | |||||
| public class SwaggerConfigureOptions : IConfigureOptions<SwaggerGenOptions> | |||||
| { | |||||
| private readonly IApiVersionDescriptionProvider _provider; | |||||
| public SwaggerConfigureOptions(IApiVersionDescriptionProvider provider) => _provider = provider; | |||||
| public void Configure(SwaggerGenOptions options) | |||||
| { | |||||
| // add swagger document for every API version discovered | |||||
| foreach (var description in _provider.ApiVersionDescriptions) | |||||
| { | |||||
| options.SwaggerDoc( | |||||
| description.GroupName, | |||||
| CreateVersionInfo(description)); | |||||
| } | |||||
| } | |||||
| public void Configure(string name, SwaggerGenOptions options) | |||||
| { | |||||
| Configure(options); | |||||
| } | |||||
| private OpenApiInfo CreateVersionInfo( | |||||
| ApiVersionDescription description) | |||||
| { | |||||
| var info = new OpenApiInfo() | |||||
| { | |||||
| Title = "Diligent Web API", | |||||
| Version = description.ApiVersion.ToString() | |||||
| }; | |||||
| if (description.IsDeprecated) | |||||
| { | |||||
| info.Description += " This API version has been deprecated."; | |||||
| } | |||||
| return info; | |||||
| } | |||||
| } | |||||
| } | |||||
| var builder = WebApplication.CreateBuilder(args); | |||||
| builder.ConfigureHost(); | |||||
| builder.ConfigureData(); | |||||
| builder.ConfigureBusiness(); | |||||
| var app = builder.Build(); | |||||
| app.ConfigureHost(); | |||||
| app.ConfigureData(); | |||||
| app.ConfigureBusiness(); | |||||
| app.Run(); |
| { | |||||
| "$schema": "https://json.schemastore.org/launchsettings.json", | |||||
| "iisSettings": { | |||||
| "windowsAuthentication": false, | |||||
| "anonymousAuthentication": true, | |||||
| "iisExpress": { | |||||
| "applicationUrl": "http://localhost:26081", | |||||
| "sslPort": 0 | |||||
| } | |||||
| }, | |||||
| "profiles": { | |||||
| "Diligent.WebAPI.Host": { | |||||
| "commandName": "Project", | |||||
| "environmentVariables": { | |||||
| "ASPNETCORE_ENVIRONMENT": "Development" | |||||
| }, | |||||
| "applicationUrl": "http://localhost:5116", | |||||
| "dotnetRunMessages": true | |||||
| }, | |||||
| "IIS Express": { | |||||
| "commandName": "IISExpress", | |||||
| "launchBrowser": true, | |||||
| "launchUrl": "", | |||||
| "environmentVariables": { | |||||
| "ASPNETCORE_ENVIRONMENT": "Development" | |||||
| } | |||||
| } | |||||
| } | |||||
| } |
| global using Diligent.WebAPI.Host.Extensions; | |||||
| global using Diligent.WebAPI.Host.Middlewares; | |||||
| global using Diligent.WebAPI.Host.Options; | |||||
| global using Diligent.WebAPI.Host.Attributes; | |||||
| global using Diligent.WebAPI.Data.Extensions; | |||||
| global using Diligent.WebAPI.Data.Entities; | |||||
| global using Diligent.WebAPI.Business.Settings; | |||||
| global using Diligent.WebAPI.Business.Services; | |||||
| global using Diligent.WebAPI.Business.Services.Interfaces; | |||||
| global using Diligent.WebAPI.Business.MappingProfiles; | |||||
| global using Diligent.WebAPI.Contracts.DTOs.Error; | |||||
| global using Diligent.WebAPI.Contracts.DTOs.InsuranceCompany; | |||||
| global using Diligent.WebAPI.Contracts.DTOs.InsurancePolicy; | |||||
| global using Diligent.WebAPI.Contracts.DTOs.Insurer; | |||||
| global using Diligent.WebAPI.Contracts.DTOs.WebhookSubscription; | |||||
| global using Diligent.WebAPI.Contracts.DTOs.WebhookDefinition; | |||||
| global using Diligent.WebAPI.Contracts.DTOs.Auth; | |||||
| global using Microsoft.AspNetCore.Mvc; | |||||
| global using Microsoft.AspNetCore.Mvc.Versioning; | |||||
| global using Microsoft.AspNetCore.Mvc.ApiExplorer; | |||||
| global using Microsoft.Extensions.Options; | |||||
| global using Microsoft.OpenApi.Models; | |||||
| global using Microsoft.AspNetCore.Mvc.Filters; | |||||
| global using Microsoft.IdentityModel.Tokens; | |||||
| global using System.Reflection; | |||||
| global using System.Net; | |||||
| global using System.Text; | |||||
| global using System.IdentityModel.Tokens.Jwt; | |||||
| global using AutoMapper; | |||||
| global using Swashbuckle.AspNetCore.SwaggerGen; |
| { | |||||
| "ConnectionStrings": { | |||||
| "WebApi": "Data Source=localhost,2433;User=sa;Password=developer_pw;Initial Catalog=WebApiDB;MultipleActiveResultSets=True" | |||||
| }, | |||||
| "Authorization": { | |||||
| "Secret": "SECRET_ASKGFH#$_#((Y)#I%EWJGDSJTGKEOS@$SAF" | |||||
| } | |||||
| } |
| { | |||||
| } |
| // <autogenerated /> | |||||
| using System; | |||||
| using System.Reflection; | |||||
| [assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")] |
| //------------------------------------------------------------------------------ | |||||
| // <auto-generated> | |||||
| // This code was generated by a tool. | |||||
| // Runtime Version:4.0.30319.42000 | |||||
| // | |||||
| // Changes to this file may cause incorrect behavior and will be lost if | |||||
| // the code is regenerated. | |||||
| // </auto-generated> | |||||
| //------------------------------------------------------------------------------ | |||||
| using System; | |||||
| using System.Reflection; | |||||
| [assembly: System.Reflection.AssemblyCompanyAttribute("Diligent.WebAPI.Shared")] | |||||
| [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] | |||||
| [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] | |||||
| [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")] | |||||
| [assembly: System.Reflection.AssemblyProductAttribute("Diligent.WebAPI.Shared")] | |||||
| [assembly: System.Reflection.AssemblyTitleAttribute("Diligent.WebAPI.Shared")] | |||||
| [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] | |||||
| // Generated by the MSBuild WriteCodeFragment class. | |||||
| dfb1355104d7a91099e3ba180c907a817966e3c1 |
| is_global = true | |||||
| build_property.TargetFramework = net6.0 | |||||
| build_property.TargetPlatformMinVersion = | |||||
| build_property.UsingMicrosoftNETSdkWeb = | |||||
| build_property.ProjectTypeGuids = | |||||
| build_property.InvariantGlobalization = | |||||
| build_property.PlatformNeutralAssembly = | |||||
| build_property._SupportedPlatformList = Linux,macOS,Windows | |||||
| build_property.RootNamespace = Diligent.WebAPI.Shared | |||||
| build_property.ProjectDir = C:\Users\safet.purkovic\source\repos\WebAPI Template - Configuration 1\Diligent.WebAPI.Shared\ |
| // <auto-generated/> | |||||
| global using global::System; | |||||
| global using global::System.Collections.Generic; | |||||
| global using global::System.IO; | |||||
| global using global::System.Linq; | |||||
| global using global::System.Net.Http; | |||||
| global using global::System.Threading; | |||||
| global using global::System.Threading.Tasks; |