diff --git a/DamageAssesmentApi/DamageAssesment.Api.Answers/Controllers/AnswersController.cs b/DamageAssesmentApi/DamageAssesment.Api.Answers/Controllers/AnswersController.cs index a86cbf1..f794283 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Answers/Controllers/AnswersController.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Answers/Controllers/AnswersController.cs @@ -1,7 +1,6 @@ using DamageAssesment.Api.Answers.Interfaces; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; -using Microsoft.EntityFrameworkCore; -using Microsoft.OpenApi.Any; namespace DamageAssesment.Api.Answers.Controllers { @@ -16,7 +15,7 @@ namespace DamageAssesment.Api.Answers.Controllers /// /// Get all answers /// - + [Authorize(Roles = "admin")] [HttpGet("Answers")] public async Task GetAnswersAsync() { @@ -32,7 +31,7 @@ namespace DamageAssesment.Api.Answers.Controllers /// Get an answer based on answerId. /// - + [Authorize(Roles = "admin")] [HttpGet("Answers/{Id}")] public async Task GetAnswerByIdAsync(int Id) { @@ -48,6 +47,7 @@ namespace DamageAssesment.Api.Answers.Controllers /// /// Get all answers based on responseId. /// + [Authorize(Roles = "admin")] [HttpGet("Answers/ByResponse/{responseid}")] public async Task GetAnswersByResponseId(int responseid) { @@ -61,7 +61,7 @@ namespace DamageAssesment.Api.Answers.Controllers /// /// Get all answers based on questionId. /// - + [Authorize(Roles = "admin")] [HttpGet("Answers/ByQuestion/{questionid}")] public async Task AnswersByQuestionId(int questionid) { @@ -75,7 +75,7 @@ namespace DamageAssesment.Api.Answers.Controllers /// /// Update an existing answer. /// - + [Authorize(Roles = "admin")] [HttpPut("Answers")] public async Task UpdateAnswer(Models.Answer answer) { @@ -96,7 +96,7 @@ namespace DamageAssesment.Api.Answers.Controllers /// /// Save a new answer. /// - + [Authorize(Roles = "admin")] [HttpPost("Answers")] public async Task CreateAnswer(Models.Answer answer) { @@ -114,7 +114,7 @@ namespace DamageAssesment.Api.Answers.Controllers /// /// Delete an existing answer. /// - + [Authorize(Roles = "admin")] [HttpDelete("Answers/{id}")] public async Task DeleteAnswer(int id) { diff --git a/DamageAssesmentApi/DamageAssesment.Api.Answers/Program.cs b/DamageAssesmentApi/DamageAssesment.Api.Answers/Program.cs index 0a38399..77e7544 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Answers/Program.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Answers/Program.cs @@ -1,23 +1,73 @@ using DamageAssesment.Api.Answers.Db; using DamageAssesment.Api.Answers.Interfaces; using DamageAssesment.Api.Answers.Providers; +using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.EntityFrameworkCore; +using Microsoft.IdentityModel.Tokens; +using Microsoft.OpenApi.Models; using System.Reflection; +using System.Text; var builder = WebApplication.CreateBuilder(args); - +var authkey = builder.Configuration.GetValue("JwtSettings:securitykey"); +builder.Services.AddAuthentication(item => +{ + item.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; + item.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; +}).AddJwtBearer(item => +{ + item.RequireHttpsMetadata = true; + item.SaveToken = true; + item.TokenValidationParameters = new TokenValidationParameters() + { + ValidateIssuerSigningKey = true, + IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(authkey)), + ValidateIssuer = false, + ValidateAudience = false, + ClockSkew = TimeSpan.Zero + }; +}); // Add services to the container. builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); //builder.Services.AddSwaggerGen(); -builder.Services.AddSwaggerGen(c => +builder.Services.AddSwaggerGen(options => { // Include XML comments from your assembly var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); - c.IncludeXmlComments(xmlPath); + options.IncludeXmlComments(xmlPath); + + OpenApiSecurityScheme securityDefinition = new OpenApiSecurityScheme() + { + Name = "Bearer", + BearerFormat = "JWT", + Scheme = "bearer", + Description = "Specify the authorization token.", + In = ParameterLocation.Header, + Type = SecuritySchemeType.Http, + }; + + options.AddSecurityDefinition("jwt_auth", securityDefinition); + + // Make sure swagger UI requires a Bearer token specified + OpenApiSecurityScheme securityScheme = new OpenApiSecurityScheme() + { + Reference = new OpenApiReference() + { + Id = "jwt_auth", + Type = ReferenceType.SecurityScheme + } + }; + + OpenApiSecurityRequirement securityRequirements = new OpenApiSecurityRequirement() + { + {securityScheme, new string[] { }}, + }; + + options.AddSecurityRequirement(securityRequirements); }); builder.Services.AddScoped(); builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies()); //4/30 @@ -35,7 +85,7 @@ if (app.Environment.IsDevelopment()) app.UseSwagger(); app.UseSwaggerUI(); } - +app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); diff --git a/DamageAssesmentApi/DamageAssesment.Api.Attachments/Controllers/AttachmentsController.cs b/DamageAssesmentApi/DamageAssesment.Api.Attachments/Controllers/AttachmentsController.cs index 0fcec65..4245281 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Attachments/Controllers/AttachmentsController.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Attachments/Controllers/AttachmentsController.cs @@ -1,6 +1,7 @@ using Azure; using DamageAssesment.Api.Attachments.Interfaces; using DamageAssesment.Api.Attachments.Models; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using System.Net.Http.Headers; @@ -21,7 +22,7 @@ namespace DamageAssesment.Api.Attachments.Controllers /// /// Get all attachments. /// - + [Authorize(Roles = "admin")] [HttpGet("Attachments")] public async Task GetAttachmentsAsync() { @@ -37,6 +38,7 @@ namespace DamageAssesment.Api.Attachments.Controllers /// /// Get all attachments by attachmentId. /// + [Authorize(Roles = "admin")] [HttpGet("Attachments/{id}")] public async Task GetAttachmentbyIdAsync(int id) { @@ -80,7 +82,7 @@ namespace DamageAssesment.Api.Attachments.Controllers /// /// Save new Attachment(s) /// - + [Authorize(Roles = "admin")] [HttpPost("Attachments"), DisableRequestSizeLimit] public async Task UploadAttachmentAsync(AttachmentInfo attachmentInfo) { @@ -107,7 +109,7 @@ namespace DamageAssesment.Api.Attachments.Controllers /// /// Modify an new attachment. /// - + [Authorize(Roles = "admin")] [HttpPut("Attachments"), DisableRequestSizeLimit] public async Task UpdateAttachmentAsync(AttachmentInfo attachmentInfo) { @@ -138,6 +140,7 @@ namespace DamageAssesment.Api.Attachments.Controllers /// /// Delete an existing attachment. /// + [Authorize(Roles = "admin")] [HttpDelete("Attachments/{id}")] public async Task DeleteAttachment(int id) { diff --git a/DamageAssesmentApi/DamageAssesment.Api.Attachments/Program.cs b/DamageAssesmentApi/DamageAssesment.Api.Attachments/Program.cs index 4fd2e59..62cf0cb 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Attachments/Program.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Attachments/Program.cs @@ -1,25 +1,75 @@ using DamageAssesment.Api.Attachments.Db; using DamageAssesment.Api.Attachments.Interfaces; using DamageAssesment.Api.Attachments.Providers; +using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Http.Features; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.FileProviders; +using Microsoft.IdentityModel.Tokens; +using Microsoft.OpenApi.Models; using System.Reflection; +using System.Text; var builder = WebApplication.CreateBuilder(args); - +var authkey = builder.Configuration.GetValue("JwtSettings:securitykey"); +builder.Services.AddAuthentication(item => +{ + item.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; + item.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; +}).AddJwtBearer(item => +{ + item.RequireHttpsMetadata = true; + item.SaveToken = true; + item.TokenValidationParameters = new TokenValidationParameters() + { + ValidateIssuerSigningKey = true, + IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(authkey)), + ValidateIssuer = false, + ValidateAudience = false, + ClockSkew = TimeSpan.Zero + }; +}); // Add services to the container. builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); //builder.Services.AddSwaggerGen(); -builder.Services.AddSwaggerGen(c => +builder.Services.AddSwaggerGen(options => { // Include XML comments from your assembly var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); - c.IncludeXmlComments(xmlPath); + options.IncludeXmlComments(xmlPath); + + OpenApiSecurityScheme securityDefinition = new OpenApiSecurityScheme() + { + Name = "Bearer", + BearerFormat = "JWT", + Scheme = "bearer", + Description = "Specify the authorization token.", + In = ParameterLocation.Header, + Type = SecuritySchemeType.Http, + }; + + options.AddSecurityDefinition("jwt_auth", securityDefinition); + + // Make sure swagger UI requires a Bearer token specified + OpenApiSecurityScheme securityScheme = new OpenApiSecurityScheme() + { + Reference = new OpenApiReference() + { + Id = "jwt_auth", + Type = ReferenceType.SecurityScheme + } + }; + + OpenApiSecurityRequirement securityRequirements = new OpenApiSecurityRequirement() + { + {securityScheme, new string[] { }}, + }; + + options.AddSecurityRequirement(securityRequirements); }); builder.Services.AddScoped(); builder.Services.AddScoped(); @@ -45,6 +95,7 @@ if (app.Environment.IsDevelopment()) app.UseSwaggerUI(); } +app.UseAuthentication(); app.UseAuthorization(); app.UseHttpsRedirection(); diff --git a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Controllers/DoculinkController.cs b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Controllers/DoculinkController.cs index cfbd508..b080635 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Controllers/DoculinkController.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Controllers/DoculinkController.cs @@ -2,6 +2,7 @@ using DamageAssesment.Api.DocuLinks.Interfaces; using DamageAssesment.Api.DocuLinks.Models; using DamageAssesment.Api.DocuLinks.Providers; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; @@ -24,6 +25,7 @@ namespace DamageAssesment.Api.DocuLinks.Controllers /// Get all Doculink type. /// [HttpGet] + [Authorize(Roles = "admin")] [Route("doculinks/types")] [Route("doculinks/types/{language:alpha}")] public async Task GetLinkTypesAsync(string? language) @@ -38,6 +40,7 @@ namespace DamageAssesment.Api.DocuLinks.Controllers /// /// Get a Doculink type by id. /// + [Authorize(Roles = "admin")] [HttpGet] [Route("doculinks/types/{id}")] [Route("doculinks/types/{id}/{language:alpha}")] @@ -53,6 +56,7 @@ namespace DamageAssesment.Api.DocuLinks.Controllers /// /// Update a existing Doculink type. /// + [Authorize(Roles = "admin")] [HttpPut] [Route("doculinks/types/{id}")] public async Task UpdateLinkType(int id,Models.LinkType linkType) @@ -74,6 +78,7 @@ namespace DamageAssesment.Api.DocuLinks.Controllers /// /// Create a new Doculink type. /// + [Authorize(Roles = "admin")] [HttpPost] [Route("doculinks/types")] public async Task CreateLinkType(Models.LinkType linkType) @@ -92,6 +97,7 @@ namespace DamageAssesment.Api.DocuLinks.Controllers /// /// Delete a existing Doculink type by id. /// + [Authorize(Roles = "admin")] [HttpDelete] [Route("doculinks/types/{id}")] public async Task DeleteLinkType(int id) @@ -104,9 +110,10 @@ namespace DamageAssesment.Api.DocuLinks.Controllers return NotFound(); } /// - /// Get all Doculink. + /// Get all documents. /// - /// + + [Authorize(Roles = "admin")] [Route("doculinks")] [Route("doculinks/{linktype:alpha}")] [Route("doculinks/{linktype:alpha}/{language:alpha}")] @@ -140,6 +147,7 @@ namespace DamageAssesment.Api.DocuLinks.Controllers /// /// Get a Doculink by id. /// + [Authorize(Roles = "admin")] [HttpGet] [Route("doculinks/{id}")] [Route("doculinks/{id}/{linktype:alpha}")] @@ -156,6 +164,7 @@ namespace DamageAssesment.Api.DocuLinks.Controllers /// /// update existing doclink. /// + [Authorize(Roles = "admin")] [HttpPut] [Route("doculinks/{id}")] public async Task UpdateDocument(int id,ReqDoculink documentInfo) @@ -181,6 +190,7 @@ namespace DamageAssesment.Api.DocuLinks.Controllers /// /// Create new doclink. /// + [Authorize(Roles = "admin")] [HttpPost] [Route("doculinks")] public async Task CreateDocument(ReqDoculink documentInfo) @@ -208,6 +218,7 @@ namespace DamageAssesment.Api.DocuLinks.Controllers /// /// Delete Doculink by id. /// + [Authorize(Roles = "admin")] [HttpDelete] [Route("doculinks/{id}")] public async Task DeleteDocument(int id) diff --git a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/DamageAssesment.Api.DocuLinks.csproj b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/DamageAssesment.Api.DocuLinks.csproj index b71afa9..a1d917b 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/DamageAssesment.Api.DocuLinks.csproj +++ b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/DamageAssesment.Api.DocuLinks.csproj @@ -10,6 +10,7 @@ + diff --git a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Program.cs b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Program.cs index f28dd76..e75e14f 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Program.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Program.cs @@ -2,19 +2,69 @@ using DamageAssesment.Api.DocuLinks.Db; using DamageAssesment.Api.DocuLinks.Interfaces; using DamageAssesment.Api.DocuLinks.Providers; using Microsoft.EntityFrameworkCore; +using Microsoft.AspNetCore.Authentication.JwtBearer; +using Microsoft.IdentityModel.Tokens; using System.Reflection; +using System.Text; +using Microsoft.OpenApi.Models; var builder = WebApplication.CreateBuilder(args); // Add services to the container. - +var authkey = builder.Configuration.GetValue("JwtSettings:securitykey"); +builder.Services.AddAuthentication(item => +{ + item.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; + item.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; +}).AddJwtBearer(item => +{ + item.RequireHttpsMetadata = true; + item.SaveToken = true; + item.TokenValidationParameters = new TokenValidationParameters() + { + ValidateIssuerSigningKey = true, + IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(authkey)), + ValidateIssuer = false, + ValidateAudience = false, + ClockSkew = TimeSpan.Zero + }; +}); builder.Services.AddControllers(); -builder.Services.AddSwaggerGen(c => +builder.Services.AddSwaggerGen(options => { // Include XML comments from your assembly var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); - c.IncludeXmlComments(xmlPath); + options.IncludeXmlComments(xmlPath); + + OpenApiSecurityScheme securityDefinition = new OpenApiSecurityScheme() + { + Name = "Bearer", + BearerFormat = "JWT", + Scheme = "bearer", + Description = "Specify the authorization token.", + In = ParameterLocation.Header, + Type = SecuritySchemeType.Http, + }; + + options.AddSecurityDefinition("jwt_auth", securityDefinition); + + // Make sure swagger UI requires a Bearer token specified + OpenApiSecurityScheme securityScheme = new OpenApiSecurityScheme() + { + Reference = new OpenApiReference() + { + Id = "jwt_auth", + Type = ReferenceType.SecurityScheme + } + }; + + OpenApiSecurityRequirement securityRequirements = new OpenApiSecurityRequirement() + { + {securityScheme, new string[] { }}, + }; + + options.AddSecurityRequirement(securityRequirements); }); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); @@ -36,6 +86,7 @@ if (app.Environment.IsDevelopment()) app.UseSwaggerUI(); } +app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); diff --git a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Properties/launchSettings.json b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Properties/launchSettings.json index e4e08ae..fcc4c27 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Properties/launchSettings.json +++ b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Properties/launchSettings.json @@ -14,7 +14,7 @@ "dotnetRunMessages": true, "launchBrowser": true, "launchUrl": "swagger", - "applicationUrl": "http://localhost:5133", + "applicationUrl": "http://localhost:5136", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } diff --git a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/appsettings.json b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/appsettings.json index 46db839..81ce9ee 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/appsettings.json +++ b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/appsettings.json @@ -1,4 +1,7 @@ { + "JwtSettings": { + "securitykey": "bWlhbWkgZGFkZSBzY2hvb2xzIHNlY3JldCBrZXk=" + }, "Logging": { "LogLevel": { "Default": "Information", diff --git a/DamageAssesmentApi/DamageAssesment.Api.Employees/Controllers/EmployeesController.cs b/DamageAssesmentApi/DamageAssesment.Api.Employees/Controllers/EmployeesController.cs index f5e0d88..019df03 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Employees/Controllers/EmployeesController.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Employees/Controllers/EmployeesController.cs @@ -1,4 +1,5 @@ using DamageAssesment.Api.Employees.Interfaces; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; @@ -18,7 +19,7 @@ namespace DamageAssesment.Api.Employees.Controllers /// /// GET request for retrieving employees. /// - + [Authorize(Roles = "admin")] [HttpGet("Employees")] public async Task GetEmployeesAsync() { @@ -35,7 +36,7 @@ namespace DamageAssesment.Api.Employees.Controllers /// /// GET request for retrieving an employee by ID. /// - + [Authorize(Roles = "admin")] [HttpGet("Employees/{id}")] public async Task GetEmployeeByIdAsync(int id) { @@ -48,11 +49,12 @@ namespace DamageAssesment.Api.Employees.Controllers return NotFound(); } - + /// /// PUT request for updating an existing employee. /// /// The updated employee object. + [Authorize(Roles = "admin")] [HttpPut("Employees/{id}")] public async Task UpdateEmployee(int id, Models.Employee Employee) { @@ -75,6 +77,7 @@ namespace DamageAssesment.Api.Employees.Controllers /// POST request for creating a new employee. /// /// The employee information for creating a new employee. + [Authorize(Roles = "admin")] [HttpPost("Employees")] public async Task CreateEmployee(Models.Employee Employee) { @@ -93,6 +96,7 @@ namespace DamageAssesment.Api.Employees.Controllers /// DELETE request for deleting an existing employee. /// /// The ID of the employee to be deleted. + [Authorize(Roles = "admin")] [HttpDelete("Employees/{id}")] public async Task DeleteEmployee(int id) { diff --git a/DamageAssesmentApi/DamageAssesment.Api.Employees/Program.cs b/DamageAssesmentApi/DamageAssesment.Api.Employees/Program.cs index 7d61871..0702b58 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Employees/Program.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Employees/Program.cs @@ -1,23 +1,74 @@ using DamageAssesment.Api.Employees.Db; using DamageAssesment.Api.Employees.Interfaces; using DamageAssesment.Api.Employees.Providers; +using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.EntityFrameworkCore; +using Microsoft.IdentityModel.Tokens; +using Microsoft.OpenApi.Models; using System.Reflection; +using System.Text; var builder = WebApplication.CreateBuilder(args); // Add services to the container. +var authkey = builder.Configuration.GetValue("JwtSettings:securitykey"); +builder.Services.AddAuthentication(item => +{ + item.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; + item.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; +}).AddJwtBearer(item => +{ + item.RequireHttpsMetadata = true; + item.SaveToken = true; + item.TokenValidationParameters = new TokenValidationParameters() + { + ValidateIssuerSigningKey = true, + IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(authkey)), + ValidateIssuer = false, + ValidateAudience = false, + ClockSkew = TimeSpan.Zero + }; +}); builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); //builder.Services.AddSwaggerGen(); -builder.Services.AddSwaggerGen(c => +builder.Services.AddSwaggerGen(options => { // Include XML comments from your assembly var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); - c.IncludeXmlComments(xmlPath); + options.IncludeXmlComments(xmlPath); + + OpenApiSecurityScheme securityDefinition = new OpenApiSecurityScheme() + { + Name = "Bearer", + BearerFormat = "JWT", + Scheme = "bearer", + Description = "Specify the authorization token.", + In = ParameterLocation.Header, + Type = SecuritySchemeType.Http, + }; + + options.AddSecurityDefinition("jwt_auth", securityDefinition); + + // Make sure swagger UI requires a Bearer token specified + OpenApiSecurityScheme securityScheme = new OpenApiSecurityScheme() + { + Reference = new OpenApiReference() + { + Id = "jwt_auth", + Type = ReferenceType.SecurityScheme + } + }; + + OpenApiSecurityRequirement securityRequirements = new OpenApiSecurityRequirement() + { + {securityScheme, new string[] { }}, + }; + + options.AddSecurityRequirement(securityRequirements); }); builder.Services.AddScoped(); @@ -43,6 +94,7 @@ if (app.Environment.IsDevelopment()) } } +app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); diff --git a/DamageAssesmentApi/DamageAssesment.Api.Employees/appsettings.json b/DamageAssesmentApi/DamageAssesment.Api.Employees/appsettings.json index daf21ba..5d5c0ca 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Employees/appsettings.json +++ b/DamageAssesmentApi/DamageAssesment.Api.Employees/appsettings.json @@ -9,14 +9,6 @@ } }, "AllowedHosts": "*", - "settings": { - "endpoint1": "xxx", - "endpoint2": "xxx", - "endpoint3": "xxx" - }, - //"ConnectionStrings": { - // "EmployeeConnection": "Server=DESKTOP-OF5DPLQ\\SQLEXPRESS;Database=da_survey_dev;Trusted_Connection=True;TrustServerCertificate=True;" - //}, "ConnectionStrings": { "EmployeeConnection": "Server=tcp:da-dev.database.windows.net,1433;Initial Catalog=da-dev-db;Encrypt=True;User ID=admin-dev;Password=b3tgRABw8LGE75k;TrustServerCertificate=False;Connection Timeout=30;" diff --git a/DamageAssesmentApi/DamageAssesment.Api.Locations/Controllers/LocationsController.cs b/DamageAssesmentApi/DamageAssesment.Api.Locations/Controllers/LocationsController.cs index d9bbea3..da06bee 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Locations/Controllers/LocationsController.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Locations/Controllers/LocationsController.cs @@ -1,4 +1,5 @@ using DamageAssesment.Api.Locations.Interfaces; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; @@ -15,7 +16,7 @@ namespace DamageAssesment.Api.Locations.Controllers /// /// Get all locations. /// - + [Authorize(Roles = "admin")] [HttpGet("Locations")] public async Task GetLocationsAsync() { @@ -31,7 +32,7 @@ namespace DamageAssesment.Api.Locations.Controllers /// /// Get all locations based on locationdId. /// - + [Authorize(Roles = "admin")] [HttpGet("Locations/{id}")] public async Task GetLocationByIdAsync(int id) { @@ -47,7 +48,7 @@ namespace DamageAssesment.Api.Locations.Controllers /// /// Update a Location. /// - + [Authorize(Roles = "admin")] [HttpPut("Locations/{id}")] public async Task UpdateLocation(int id, Models.Location Location) { @@ -65,7 +66,7 @@ namespace DamageAssesment.Api.Locations.Controllers /// /// Save a new location. /// - + [Authorize(Roles = "admin")] [HttpPost("Locations")] public async Task CreateLocation(Models.Location Location) { @@ -83,7 +84,7 @@ namespace DamageAssesment.Api.Locations.Controllers /// /// Delete an existing location. /// - + [Authorize(Roles = "admin")] [HttpDelete("Locations/{id}")] public async Task DeleteLocation(int id) { diff --git a/DamageAssesmentApi/DamageAssesment.Api.Locations/Controllers/RegionsController.cs b/DamageAssesmentApi/DamageAssesment.Api.Locations/Controllers/RegionsController.cs index 172043c..d7fe03c 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Locations/Controllers/RegionsController.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Locations/Controllers/RegionsController.cs @@ -1,4 +1,5 @@ using DamageAssesment.Api.Locations.Interfaces; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; namespace DamageAssesment.Api.Locations.Controllers @@ -15,7 +16,7 @@ namespace DamageAssesment.Api.Locations.Controllers /// /// Get all regions.2 /// - + [Authorize(Roles = "admin")] [HttpGet("regions")] public async Task GetRegionsAsync() { @@ -29,7 +30,7 @@ namespace DamageAssesment.Api.Locations.Controllers /// /// GET request for retrieving a region by its ID. /// - + [Authorize(Roles = "admin")] [HttpGet("regions/{id}")] public async Task GetRegionAsync(int id) { @@ -43,7 +44,7 @@ namespace DamageAssesment.Api.Locations.Controllers /// /// POST request for creating a new region. /// - + [Authorize(Roles = "admin")] [HttpPost("regions")] public async Task PostRegionAsync(Models.Region region) { @@ -57,7 +58,7 @@ namespace DamageAssesment.Api.Locations.Controllers /// /// PUT request for updating an existing region. /// - + [Authorize(Roles = "admin")] [HttpPut("regions/{id}")] public async Task PutRegionAsync(int id, Models.Region region) { @@ -75,7 +76,7 @@ namespace DamageAssesment.Api.Locations.Controllers /// DELETE request for deleting a region based on ID. /// - + [Authorize(Roles = "admin")] [HttpDelete("regions/{id}")] public async Task DeleteRegionAsync(int id) { diff --git a/DamageAssesmentApi/DamageAssesment.Api.Locations/Program.cs b/DamageAssesmentApi/DamageAssesment.Api.Locations/Program.cs index f8136bd..cf4c0d2 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Locations/Program.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Locations/Program.cs @@ -1,23 +1,73 @@ using DamageAssesment.Api.Locations.Db; using DamageAssesment.Api.Locations.Interfaces; using DamageAssesment.Api.Locations.Providers; +using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.EntityFrameworkCore; +using Microsoft.IdentityModel.Tokens; +using Microsoft.OpenApi.Models; using System.Reflection; +using System.Text; var builder = WebApplication.CreateBuilder(args); // Add services to the container. - +var authkey = builder.Configuration.GetValue("JwtSettings:securitykey"); +builder.Services.AddAuthentication(item => +{ + item.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; + item.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; +}).AddJwtBearer(item => +{ + item.RequireHttpsMetadata = true; + item.SaveToken = true; + item.TokenValidationParameters = new TokenValidationParameters() + { + ValidateIssuerSigningKey = true, + IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(authkey)), + ValidateIssuer = false, + ValidateAudience = false, + ClockSkew = TimeSpan.Zero + }; +}); builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); //builder.Services.AddSwaggerGen(); -builder.Services.AddSwaggerGen(c => +builder.Services.AddSwaggerGen(options => { // Include XML comments from your assembly var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); - c.IncludeXmlComments(xmlPath); + options.IncludeXmlComments(xmlPath); + + OpenApiSecurityScheme securityDefinition = new OpenApiSecurityScheme() + { + Name = "Bearer", + BearerFormat = "JWT", + Scheme = "bearer", + Description = "Specify the authorization token.", + In = ParameterLocation.Header, + Type = SecuritySchemeType.Http, + }; + + options.AddSecurityDefinition("jwt_auth", securityDefinition); + + // Make sure swagger UI requires a Bearer token specified + OpenApiSecurityScheme securityScheme = new OpenApiSecurityScheme() + { + Reference = new OpenApiReference() + { + Id = "jwt_auth", + Type = ReferenceType.SecurityScheme + } + }; + + OpenApiSecurityRequirement securityRequirements = new OpenApiSecurityRequirement() + { + {securityScheme, new string[] { }}, + }; + + options.AddSecurityRequirement(securityRequirements); }); builder.Services.AddScoped(); builder.Services.AddScoped(); @@ -26,7 +76,10 @@ builder.Services.AddDbContext(option => { option.UseSqlServer("LocationConnection"); }); + + var app = builder.Build(); +// Add services to the container. // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) @@ -44,6 +97,7 @@ if (app.Environment.IsDevelopment()) } } +app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); diff --git a/DamageAssesmentApi/DamageAssesment.Api.Questions/Controllers/QuestionsController.cs b/DamageAssesmentApi/DamageAssesment.Api.Questions/Controllers/QuestionsController.cs index 17024eb..3799b40 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Questions/Controllers/QuestionsController.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Questions/Controllers/QuestionsController.cs @@ -1,4 +1,5 @@ using DamageAssesment.Api.Questions.Interfaces; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; namespace DamageAssesment.Api.Questions.Controllers @@ -10,16 +11,14 @@ namespace DamageAssesment.Api.Questions.Controllers public QuestionsController(IQuestionsProvider questionsProvider) { - this.questionsProvider = questionsProvider; - } - /// /// GET request for retrieving questions. /// - // get all questions + //get all questions + [Authorize(Roles = "admin,survey,user,report")] [Route("Questions")] [Route("Questions/{language:alpha}")] [HttpGet] @@ -37,6 +36,7 @@ namespace DamageAssesment.Api.Questions.Controllers /// /// GET request for retrieving a question by ID. /// + [Authorize(Roles = "admin,survey,user,report")] [Route("Questions/{id}/{language:alpha}")] [Route("Questions/{id:int}")] [HttpGet] @@ -55,6 +55,7 @@ namespace DamageAssesment.Api.Questions.Controllers /// GET request for retrieving survey questions based on a survey ID. /// Uri: {Optional language}/GetSurveyQuestions/{surveyId} :Default returns question in all languages /// + [Authorize(Roles = "admin,survey,user,report")] [Route("Questions/BySurvey/{surveyId:int}")] [Route("Questions/BySurvey/{surveyId:int}/{language:alpha}")] [HttpGet] @@ -71,6 +72,7 @@ namespace DamageAssesment.Api.Questions.Controllers /// PUT request for updating a question (multilingual). /// + [Authorize(Roles = "admin")] [HttpPut("Questions")] public async Task UpdateQuestion(Models.Question question) { @@ -92,6 +94,7 @@ namespace DamageAssesment.Api.Questions.Controllers /// POST request for creating a new question (multilingual). /// + [Authorize(Roles = "admin")] [HttpPost("Questions")] public async Task CreateQuestion(Models.Question question) { @@ -110,6 +113,7 @@ namespace DamageAssesment.Api.Questions.Controllers /// DELETE request for deleting a question based on ID. /// + [Authorize(Roles = "admin")] [HttpDelete("Questions/{id}")] public async Task DeleteQuestion(int id) { @@ -125,6 +129,7 @@ namespace DamageAssesment.Api.Questions.Controllers /// GET request for retrieving question categories. /// + [Authorize(Roles = "admin,user,report")] [HttpGet("Questions/Categories")] [HttpGet("Questions/Categories/{language:alpha}")] public async Task GetQuestionCategoriesAsync(string? language) @@ -139,7 +144,7 @@ namespace DamageAssesment.Api.Questions.Controllers /// /// GET request for retrieving a question category by ID. /// - + [Authorize(Roles = "admin,report")] [HttpGet("Questions/Categories/{id:int}")] [HttpGet("Questions/Categories/{id:int}/{language:alpha}")] public async Task GetQuestionCategoryAsync(int id,string? language) @@ -156,7 +161,7 @@ namespace DamageAssesment.Api.Questions.Controllers /// /// PUT request for updating a question category. /// - + [Authorize(Roles = "admin,survey,report")] [HttpPut("Questions/Categories")] public async Task UpdateQuestionCategory(Models.QuestionCategory questionCategory) { @@ -178,6 +183,7 @@ namespace DamageAssesment.Api.Questions.Controllers /// POST request for creating a new question category. /// + [Authorize(Roles = "admin")] [HttpPost("Questions/Categories")] public async Task CreateQuestionCategory(Models.QuestionCategory questionCategory) { @@ -196,6 +202,7 @@ namespace DamageAssesment.Api.Questions.Controllers /// DELETE request for deleting a question category based on ID. /// + [Authorize(Roles = "admin")] [HttpDelete("Questions/Categories/{id}")] public async Task DeleteQuestionCategory(int id) { diff --git a/DamageAssesmentApi/DamageAssesment.Api.Questions/Models/Question.cs b/DamageAssesmentApi/DamageAssesment.Api.Questions/Models/Question.cs index b6c1668..f7fe7fb 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Questions/Models/Question.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Questions/Models/Question.cs @@ -12,7 +12,7 @@ public bool IsRequired { get; set; } public bool Comment { get; set; } public bool Key { get; set; } - public int? SurveyId { get; set; } + public int SurveyId { get; set; } public int CategoryId { get; set; } } } diff --git a/DamageAssesmentApi/DamageAssesment.Api.Questions/Program.cs b/DamageAssesmentApi/DamageAssesment.Api.Questions/Program.cs index c47a38d..dfd6a07 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Questions/Program.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Questions/Program.cs @@ -1,11 +1,33 @@ using DamageAssesment.Api.Questions.Db; using DamageAssesment.Api.Questions.Interfaces; using DamageAssesment.Api.Questions.Providers; +using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.EntityFrameworkCore; +using Microsoft.IdentityModel.Tokens; +using Microsoft.OpenApi.Models; using System.Reflection; +using System.Text; var builder = WebApplication.CreateBuilder(args); - +// Add services to the container. +var authkey = builder.Configuration.GetValue("JwtSettings:securitykey"); +builder.Services.AddAuthentication(item => +{ + item.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; + item.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; +}).AddJwtBearer(item => +{ + item.RequireHttpsMetadata = true; + item.SaveToken = true; + item.TokenValidationParameters = new TokenValidationParameters() + { + ValidateIssuerSigningKey = true, + IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(authkey)), + ValidateIssuer = false, + ValidateAudience = false, + ClockSkew = TimeSpan.Zero + }; +}); // Add services to the container. builder.Services.AddControllers(); @@ -17,13 +39,41 @@ builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies()); builder.Services.AddEndpointsApiExplorer(); //builder.Services.AddSwaggerGen(); -builder.Services.AddSwaggerGen(c => +builder.Services.AddSwaggerGen(options => { // Include XML comments from your assembly var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); - c.IncludeXmlComments(xmlPath); + options.IncludeXmlComments(xmlPath); + + OpenApiSecurityScheme securityDefinition = new OpenApiSecurityScheme() + { + Name = "Bearer", + BearerFormat = "JWT", + Scheme = "bearer", + Description = "Specify the authorization token.", + In = ParameterLocation.Header, + Type = SecuritySchemeType.Http, + }; + + options.AddSecurityDefinition("jwt_auth", securityDefinition); + + // Make sure swagger UI requires a Bearer token specified + OpenApiSecurityScheme securityScheme = new OpenApiSecurityScheme() + { + Reference = new OpenApiReference() + { + Id = "jwt_auth", + Type = ReferenceType.SecurityScheme + } + }; + OpenApiSecurityRequirement securityRequirements = new OpenApiSecurityRequirement() + { + {securityScheme, new string[] { }}, + }; + options.AddSecurityRequirement(securityRequirements); }); + builder.Services.AddDbContext(option => { option.UseSqlServer("QuestionConnection"); @@ -43,7 +93,7 @@ if (app.Environment.IsDevelopment()) questionProvider.SeedData(); } } - +app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); diff --git a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Controllers/SurveyResponsesController.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Controllers/ResponsesController.cs similarity index 69% rename from DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Controllers/SurveyResponsesController.cs rename to DamageAssesmentApi/DamageAssesment.Api.Responses/Controllers/ResponsesController.cs index 22d9f6b..08290e9 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Controllers/SurveyResponsesController.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Controllers/ResponsesController.cs @@ -1,28 +1,26 @@ -using DamageAssesment.Api.SurveyResponses.Interfaces; -using DamageAssesment.Api.SurveyResponses.Models; +using DamageAssesment.Api.Responses.Interfaces; +using DamageAssesment.Api.Responses.Models; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; -namespace DamageAssesment.Api.SurveyResponses.Controllers +namespace DamageAssesment.Api.Responses.Controllers { [ApiController] - public class SurveyResponsesController : ControllerBase + public class ResponsesController : ControllerBase { private readonly ISurveysResponse surveyResponseProvider; - - public SurveyResponsesController(ISurveysResponse surveyResponseProvider) + public ResponsesController(ISurveysResponse surveyResponseProvider) { this.surveyResponseProvider = surveyResponseProvider; } /// /// GET request for retrieving survey responses. /// - - [Route("Responses/{employeeid:int}")] - [Route("Responses")] - [HttpGet] - public async Task GetSurveyResponsesAsync(int? employeeid) + [Authorize(Roles = "admin,survey,user,report")] + [HttpGet("Responses")] + public async Task GetSurveyResponsesAsync() { - var result = await this.surveyResponseProvider.GetSurveyResponsesAsync(employeeid ?? 0); + var result = await this.surveyResponseProvider.GetSurveyResponsesAsync(); if (result.IsSuccess) { return Ok(result.surveyResponses); @@ -36,12 +34,11 @@ namespace DamageAssesment.Api.SurveyResponses.Controllers /// /// GET request for retrieving survey responses by survey ID. /// - [Route("Responses/BySurvey/{surveyid:int}/{employeeid:int}")] - [Route("Responses/BySurvey/{surveyid:int}")] - [HttpGet] - public async Task GetSurveyResponsesAsync(int surveyid, int? employeeid) + [Authorize(Roles = "admin,survey,user,report")] + [HttpGet("Responses/BySurvey/{surveyid}")] + public async Task GetSurveyResponsesAsync(int surveyid) { - var result = await this.surveyResponseProvider.GetSurveyResponsesBySurveyAsync(surveyid, employeeid ?? 0); + var result = await this.surveyResponseProvider.GetSurveyResponsesBySurveyAsync(surveyid); if (result.IsSuccess) { return Ok(result.SurveyResponses); @@ -53,17 +50,16 @@ namespace DamageAssesment.Api.SurveyResponses.Controllers /// /// The ID of the survey for which responses are to be retrieved. /// The ID of the location for which responses are to be retrieved. - - [Route("Responses/{surveyid:int}/{locationid:int}/{employeeid:int}")] - [Route("Responses/{surveyid:int}/{locationid:int}")] - [HttpGet] - public async Task GetSurveyResponsesBySurveyAndLocationAsync(int surveyid, int locationid,int? employeeid) + [Authorize(Roles = "admin,survey,user,report")] + [HttpGet("Responses/{surveyid}/{locationid}")] + public async Task GetSurveyResponsesBySurveyAndLocationAsync(int surveyid, int locationid) { - var result = await this.surveyResponseProvider.GetSurveyResponsesBySurveyAndLocationAsync(surveyid, locationid,employeeid ?? 0); + var result = await this.surveyResponseProvider.GetSurveyResponsesBySurveyAndLocationAsync(surveyid, locationid); if (result.IsSuccess) { return Ok(result.SurveyResponses); } + return NoContent(); } /// @@ -72,13 +68,11 @@ namespace DamageAssesment.Api.SurveyResponses.Controllers /// The ID of the survey for which responses are to be retrieved. /// The ID of the question for which responses are to be retrieved. /// The answer for which responses are to be retrieved. - - [Route("Responses/ByAnswer/{surveyid:int}/{questionid:int}/{answer:alpha}/{employeeid:int}")] - [Route("Responses/ByAnswer/{surveyid:int}/{questionid:int}/{answer:alpha}")] - [HttpGet] - public async Task GetSurveyResponsesByAnswerAsyncAsync(int surveyid, int questionid, string answer, int? employeeid) + [Authorize(Roles = "admin,survey,user,report")] + [HttpGet("Responses/ByAnswer/{surveyid}/{questionid}/{answer}")] + public async Task GetSurveyResponsesByAnswerAsyncAsync(int surveyid, int questionid, string answer) { - var result = await surveyResponseProvider.GetResponsesByAnswerAsync(surveyid, questionid, answer, employeeid ?? 0); + var result = await surveyResponseProvider.GetResponsesByAnswerAsync(surveyid, questionid, answer); if (result.IsSuccess) { return Ok(result.SurveyResponses); @@ -90,13 +84,11 @@ namespace DamageAssesment.Api.SurveyResponses.Controllers /// GET request for retrieving answers from survey responses by survey ID and region. /// /// The ID of the survey for which answers are to be retrieved. - - [Route("Responses/ByRegion/{surveyid:int}")] - [Route("Responses/ByRegion/{surveyid:int}/{employeeid}")] - [HttpGet] - public async Task GetAnswersByRegionAsync(int surveyid, int? employeeid) + [Authorize(Roles = "admin,survey,user,report")] + [HttpGet("Responses/ByRegion/{surveyid}")] + public async Task GetAnswersByRegionAsync(int surveyid) { - var result = await this.surveyResponseProvider.GetAnswersByRegionAsync(surveyid, employeeid ?? 0); + var result = await this.surveyResponseProvider.GetAnswersByRegionAsync(surveyid); if (result.IsSuccess) { return Ok(result.Answers); @@ -107,12 +99,11 @@ namespace DamageAssesment.Api.SurveyResponses.Controllers /// GET request for retrieving survey responses by survey ID and maintenance center. /// /// The ID of the survey for which responses are to be retrieved. - [Route("Responses/ByMaintenanceCenter/{surveyid:int}/{employeeid:int}")] - [Route("Responses/ByMaintenanceCenter/{surveyid:int}")] - [HttpGet] - public async Task GetAnswersByMaintenaceCentersync(int surveyid, int? employeeid) + [Authorize(Roles = "admin,survey,user,report")] + [HttpGet("Responses/ByMaintenanceCenter/{surveyid}")] + public async Task GetAnswersByMaintenaceCentersync(int surveyid) { - var result = await this.surveyResponseProvider.GetSurveyResponsesByMaintenanceCenterAsync(surveyid, employeeid ?? 0); + var result = await this.surveyResponseProvider.GetSurveyResponsesByMaintenanceCenterAsync(surveyid); if (result.IsSuccess) { return Ok(result.SurveyResponses); @@ -123,7 +114,7 @@ namespace DamageAssesment.Api.SurveyResponses.Controllers /// GET request for retrieving a survey response by response ID. /// /// The ID of the survey response to be retrieved. - + [Authorize(Roles = "admin,survey,user,report")] [HttpGet("Responses/{id}")] public async Task GetSurveyResponseByIdAsync(int id) { @@ -139,7 +130,7 @@ namespace DamageAssesment.Api.SurveyResponses.Controllers /// POST request for creating a new survey response. /// /// The survey response object to be created. - + [Authorize(Roles = "admin,survey,user,report")] [HttpPost("Responses")] public async Task PostSurveysAsync(Models.SurveyResponse surveyResponse) { @@ -155,7 +146,7 @@ namespace DamageAssesment.Api.SurveyResponses.Controllers /// /// The ID of the survey response to be updated. /// The updated survey response object. - + [Authorize(Roles = "admin,survey,user,report")] [HttpPut("Responses/{id}")] public async Task PutSurveyResponseAsync(int id, Models.SurveyResponse surveyResponse) { @@ -172,7 +163,7 @@ namespace DamageAssesment.Api.SurveyResponses.Controllers /// /// DELETE request for deleting an existing survey response. /// - + [Authorize(Roles = "admin,survey,user,report")] [HttpDelete("Responses/{id}")] public async Task DeleteSurveyResponseAsync(int id) { @@ -187,7 +178,7 @@ namespace DamageAssesment.Api.SurveyResponses.Controllers /// POST request for submitting survey with multiple answers. /// /// The answers to be submitted for the survey. - + [Authorize(Roles = "admin,survey,user,report")] [HttpPost("Responses/Answers")] public async Task PostSurveyAnswersAsync(Request request) { @@ -198,31 +189,5 @@ namespace DamageAssesment.Api.SurveyResponses.Controllers else return BadRequest(result.ErrorMessage); } - - [Route("Responses/Surveys/active/{employeeid:int}")] - [Route("Responses/Surveys/active/{employeeid:int}/{language:alpha}")] - [HttpGet] - public async Task GetActiveSurveysAsync(int employeeid, string? language) - { - var result = await this.surveyResponseProvider.GetActiveSurveysAsync(employeeid, language); - if (result.IsSuccess) - { - return Ok(result.Surveys); - } - return NoContent(); - } - - [Route("Responses/Surveys/historic/{employeeid:int}")] - [Route("Responses/Surveys/historic/{employeeid:int}/{language:alpha}")] - [HttpGet] - public async Task GetHistoricSurveysAsync(int employeeid, string? language) - { - var result = await this.surveyResponseProvider.GetHistoricSurveysAsync(employeeid, language); - if (result.IsSuccess) - { - return Ok(result.Surveys); - } - return NoContent(); - } } } diff --git a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/DamageAssesment.Api.Responses.csproj b/DamageAssesmentApi/DamageAssesment.Api.Responses/DamageAssesment.Api.Responses.csproj similarity index 100% rename from DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/DamageAssesment.Api.Responses.csproj rename to DamageAssesmentApi/DamageAssesment.Api.Responses/DamageAssesment.Api.Responses.csproj diff --git a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Db/SurveyResponse.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Db/SurveyResponse.cs similarity index 94% rename from DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Db/SurveyResponse.cs rename to DamageAssesmentApi/DamageAssesment.Api.Responses/Db/SurveyResponse.cs index 2169097..14704cb 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Db/SurveyResponse.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Db/SurveyResponse.cs @@ -1,7 +1,7 @@ using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -namespace DamageAssesment.Api.SurveyResponses.Db +namespace DamageAssesment.Api.Responses.Db { public class SurveyResponse { diff --git a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Db/SurveyResponseDbContext.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Db/SurveyResponseDbContext.cs similarity index 95% rename from DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Db/SurveyResponseDbContext.cs rename to DamageAssesmentApi/DamageAssesment.Api.Responses/Db/SurveyResponseDbContext.cs index 8520066..cc786ab 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Db/SurveyResponseDbContext.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Db/SurveyResponseDbContext.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore; -namespace DamageAssesment.Api.SurveyResponses.Db +namespace DamageAssesment.Api.Responses.Db { public class SurveyResponseDbContext:DbContext { diff --git a/DamageAssesmentApi/DamageAssesment.Api.Responses/Interfaces/IAnswerServiceProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Interfaces/IAnswerServiceProvider.cs new file mode 100644 index 0000000..7c23f55 --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Interfaces/IAnswerServiceProvider.cs @@ -0,0 +1,12 @@ +using DamageAssesment.Api.Responses.Models; + +namespace DamageAssesment.Api.Responses.Interfaces +{ + public interface IAnswerServiceProvider + { + Task> getAnswersAsync(string token); + Task> GetAnswersByResponseIdAsync(int responseId, string token); + + Task PostAnswersAsync(Models.Answer answer, string token); + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.Responses/Interfaces/IAttachmentServiceProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Interfaces/IAttachmentServiceProvider.cs new file mode 100644 index 0000000..15f76a5 --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Interfaces/IAttachmentServiceProvider.cs @@ -0,0 +1,10 @@ +using DamageAssesment.Api.Responses.Models; + +namespace DamageAssesment.Api.Responses.Interfaces +{ + public interface IAttachmentServiceProvider + { + Task> getAttachmentsAsync(string token); + Task> PostAttachmentsAsync(Models.AttachmentInfo attachmentInfo, string token); + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.Responses/Interfaces/IEmployeeServiceProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Interfaces/IEmployeeServiceProvider.cs new file mode 100644 index 0000000..b7f8143 --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Interfaces/IEmployeeServiceProvider.cs @@ -0,0 +1,10 @@ +using DamageAssesment.Api.Responses.Models; + +namespace DamageAssesment.Api.Responses.Interfaces +{ + public interface IEmployeeServiceProvider + { + Task> getEmployeesAsync(string token); + Task getEmployeeAsync(int employeeId, string token); + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.Responses/Interfaces/IHttpUtil.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Interfaces/IHttpUtil.cs new file mode 100644 index 0000000..cf63c3b --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Interfaces/IHttpUtil.cs @@ -0,0 +1,9 @@ +using DamageAssesment.Api.Responses.Models; + +namespace DamageAssesment.Api.Responses.Interfaces +{ + public interface IHttpUtil + { + Task SendAsync(HttpMethod method, string url, string JsonInput, string token); + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.Responses/Interfaces/ILocationServiceProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Interfaces/ILocationServiceProvider.cs new file mode 100644 index 0000000..75ab80e --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Interfaces/ILocationServiceProvider.cs @@ -0,0 +1,9 @@ +using DamageAssesment.Api.Responses.Models; + +namespace DamageAssesment.Api.Responses.Interfaces +{ + public interface ILocationServiceProvider + { + Task> getLocationsAsync(string token); + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.Responses/Interfaces/IQuestionServiceProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Interfaces/IQuestionServiceProvider.cs new file mode 100644 index 0000000..b37a171 --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Interfaces/IQuestionServiceProvider.cs @@ -0,0 +1,11 @@ +using DamageAssesment.Api.Responses.Models; + +namespace DamageAssesment.Api.Responses.Interfaces +{ + public interface IQuestionServiceProvider + { + Task> getQuestionsAsync(string token); + Task> getSurveyQuestionsAsync(int surveyId, string token); + Task getQuestionsAsync(int questionId, string token); + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.Responses/Interfaces/IRegionServiceProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Interfaces/IRegionServiceProvider.cs new file mode 100644 index 0000000..a97193e --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Interfaces/IRegionServiceProvider.cs @@ -0,0 +1,9 @@ +using DamageAssesment.Api.Responses.Models; + +namespace DamageAssesment.Api.Responses.Interfaces +{ + public interface IRegionServiceProvider + { + Task> getRegionsAsync(string token); + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.Responses/Interfaces/ISurveyServiceProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Interfaces/ISurveyServiceProvider.cs new file mode 100644 index 0000000..60de3bd --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Interfaces/ISurveyServiceProvider.cs @@ -0,0 +1,10 @@ +using DamageAssesment.Api.Responses.Models; + +namespace DamageAssesment.Api.Responses.Interfaces +{ + public interface ISurveyServiceProvider + { + Task> getSurveysAsync(string token); + Task getSurveyAsync(int surveyId,string token); + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Interfaces/ISurveysResponse.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Interfaces/ISurveysResponse.cs similarity index 62% rename from DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Interfaces/ISurveysResponse.cs rename to DamageAssesmentApi/DamageAssesment.Api.Responses/Interfaces/ISurveysResponse.cs index 2bbab9a..d300260 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Interfaces/ISurveysResponse.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Interfaces/ISurveysResponse.cs @@ -1,23 +1,21 @@ -using DamageAssesment.Api.SurveyResponses.Models; -using Microsoft.AspNetCore.Mvc; +using DamageAssesment.Api.Responses.Models; -namespace DamageAssesment.Api.SurveyResponses.Interfaces +namespace DamageAssesment.Api.Responses.Interfaces { public interface ISurveysResponse { - Task<(bool IsSuccess, dynamic Answers, string ErrorMessage)> GetAnswersByRegionAsync(int surveyId, int employeeid); + Task<(bool IsSuccess, dynamic Answers, string ErrorMessage)> GetAnswersByRegionAsync(int surveyId); Task<(bool IsSuccess, Models.SurveyResponse SurveyResponse, string ErrorMessage)> PostSurveyResponseAsync(Models.SurveyResponse surveyResponse); - // Task<(bool IsSuccess,dynamic surveyResponses, string ErrorMessage)> GetSurveyResponseAsync(int responseId); - Task<(bool IsSuccess, dynamic surveyResponses, string ErrorMessage)> GetSurveyResponsesAsync(int employeeid); - Task<(bool IsSuccess, dynamic Surveys, string ErrorMessage)> GetActiveSurveysAsync(int employeeid, string language); - Task<(bool IsSuccess, dynamic Surveys, string ErrorMessage)> GetHistoricSurveysAsync(int employeeid, string language); + // Task<(bool IsSuccess,dynamic surveyResponses, string ErrorMessage)> GetSurveyResponseAsync(int responseId); + Task<(bool IsSuccess, dynamic surveyResponses, string ErrorMessage)> GetSurveyResponsesAsync(); Task<(bool IsSuccess, Models.SurveyResponse SurveyResponse, string ErrorMessage)> PutSurveyResponseAsync(int Id, Models.SurveyResponse surveyResponse); Task<(bool IsSuccess, Models.SurveyResponse SurveyResponse, string ErrorMessage)> DeleteSurveyResponseAsync(int Id); Task<(bool IsSuccess, dynamic SurveyResponse, string ErrorMessage)> GetSurveyResponseByIdAsync(int responseId); - Task<(bool IsSuccess, dynamic SurveyResponses, string ErrorMessage)> GetSurveyResponsesBySurveyAsync(int surveyId, int employeeid); - Task<(bool IsSuccess, dynamic SurveyResponses, string ErrorMessage)> GetSurveyResponsesBySurveyAndLocationAsync(int surveyId, int locationId, int employeeid); - Task<(bool IsSuccess, dynamic SurveyResponses, string ErrorMessage)> GetSurveyResponsesByMaintenanceCenterAsync(int surveyId, int employeeid); - Task<(bool IsSuccess, dynamic SurveyResponses, string ErrorMessage)> GetResponsesByAnswerAsync(int surveyId, int questionId, string answer, int employeeid); + Task<(bool IsSuccess, dynamic SurveyResponses, string ErrorMessage)> GetSurveyResponsesBySurveyAsync(int surveyId); + Task<(bool IsSuccess, dynamic SurveyResponses, string ErrorMessage)> GetSurveyResponsesBySurveyAndLocationAsync(int surveyId, int locationId); + Task<(bool IsSuccess, dynamic SurveyResponses, string ErrorMessage)> GetSurveyResponsesByMaintenanceCenterAsync(int surveyId); + Task<(bool IsSuccess, dynamic SurveyResponses, string ErrorMessage)> GetResponsesByAnswerAsync(int surveyId, int questionId, string answer); + Task<(bool IsSuccess, Models.SurveyResponse SurveyResponse, string ErrorMessage)> PostSurveyAnswersAsync(Request request); } diff --git a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Migrations/20230927211458_AzureSurveyResponses.Designer.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Migrations/20230927211458_AzureSurveyResponses.Designer.cs similarity index 98% rename from DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Migrations/20230927211458_AzureSurveyResponses.Designer.cs rename to DamageAssesmentApi/DamageAssesment.Api.Responses/Migrations/20230927211458_AzureSurveyResponses.Designer.cs index 60e0615..d698544 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Migrations/20230927211458_AzureSurveyResponses.Designer.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Migrations/20230927211458_AzureSurveyResponses.Designer.cs @@ -1,6 +1,6 @@ // using System; -using DamageAssesment.Api.SurveyResponses.Db; +using DamageAssesment.Api.Responses.Db; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata; diff --git a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Migrations/20230927211458_AzureSurveyResponses.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Migrations/20230927211458_AzureSurveyResponses.cs similarity index 100% rename from DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Migrations/20230927211458_AzureSurveyResponses.cs rename to DamageAssesmentApi/DamageAssesment.Api.Responses/Migrations/20230927211458_AzureSurveyResponses.cs diff --git a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Migrations/SurveyResponseDbContextModelSnapshot.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Migrations/SurveyResponseDbContextModelSnapshot.cs similarity index 97% rename from DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Migrations/SurveyResponseDbContextModelSnapshot.cs rename to DamageAssesmentApi/DamageAssesment.Api.Responses/Migrations/SurveyResponseDbContextModelSnapshot.cs index f90e67e..20997d3 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Migrations/SurveyResponseDbContextModelSnapshot.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Migrations/SurveyResponseDbContextModelSnapshot.cs @@ -1,6 +1,6 @@ // using System; -using DamageAssesment.Api.SurveyResponses.Db; +using DamageAssesment.Api.Responses.Db; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata; diff --git a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Models/Answer.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Models/Answer.cs similarity index 90% rename from DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Models/Answer.cs rename to DamageAssesmentApi/DamageAssesment.Api.Responses/Models/Answer.cs index d607a2f..d507630 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Models/Answer.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Models/Answer.cs @@ -1,6 +1,6 @@ using System.ComponentModel.DataAnnotations; -namespace DamageAssesment.Api.SurveyResponses.Models +namespace DamageAssesment.Api.Responses.Models { public class Answer { diff --git a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Models/AnswerRequest.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Models/AnswerRequest.cs similarity index 82% rename from DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Models/AnswerRequest.cs rename to DamageAssesmentApi/DamageAssesment.Api.Responses/Models/AnswerRequest.cs index 3d86488..2921faf 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Models/AnswerRequest.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Models/AnswerRequest.cs @@ -1,4 +1,4 @@ -namespace DamageAssesment.Api.SurveyResponses.Models +namespace DamageAssesment.Api.Responses.Models { public class AnswerRequest { diff --git a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Models/Attachment.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Models/Attachment.cs similarity index 89% rename from DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Models/Attachment.cs rename to DamageAssesmentApi/DamageAssesment.Api.Responses/Models/Attachment.cs index 92ab874..6194789 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Models/Attachment.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Models/Attachment.cs @@ -1,6 +1,6 @@ using System.ComponentModel.DataAnnotations; -namespace DamageAssesment.Api.SurveyResponses.Models +namespace DamageAssesment.Api.Responses.Models { public class Attachment { diff --git a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Models/AttachmentInfo.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Models/AttachmentInfo.cs similarity index 90% rename from DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Models/AttachmentInfo.cs rename to DamageAssesmentApi/DamageAssesment.Api.Responses/Models/AttachmentInfo.cs index e3e30b9..8c31831 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Models/AttachmentInfo.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Models/AttachmentInfo.cs @@ -1,4 +1,4 @@ -namespace DamageAssesment.Api.SurveyResponses.Models +namespace DamageAssesment.Api.Responses.Models { public class AttachmentInfo { diff --git a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Models/Employee.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Models/Employee.cs similarity index 78% rename from DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Models/Employee.cs rename to DamageAssesmentApi/DamageAssesment.Api.Responses/Models/Employee.cs index 9a06020..3a84d81 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Models/Employee.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Models/Employee.cs @@ -1,6 +1,6 @@ using System.ComponentModel.DataAnnotations; -namespace DamageAssesment.Api.SurveyResponses.Models +namespace DamageAssesment.Api.Responses.Models { public class Employee { @@ -11,6 +11,6 @@ namespace DamageAssesment.Api.SurveyResponses.Models public string OfficePhoneNumber { get; set; } public string Email { get; set; } public bool IsActive { get; set; } - public string? PreferredLanguage { get; set; } + public string PreferredLanguage { get; set; } } } diff --git a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Models/Location.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Models/Location.cs similarity index 82% rename from DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Models/Location.cs rename to DamageAssesmentApi/DamageAssesment.Api.Responses/Models/Location.cs index 078a5ef..d5996d2 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Models/Location.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Models/Location.cs @@ -1,4 +1,4 @@ -namespace DamageAssesment.Api.SurveyResponses.Models +namespace DamageAssesment.Api.Responses.Models { public class Location { diff --git a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Models/Question.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Models/Question.cs similarity index 90% rename from DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Models/Question.cs rename to DamageAssesmentApi/DamageAssesment.Api.Responses/Models/Question.cs index 37abb4b..aac31f5 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Models/Question.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Models/Question.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; -namespace DamageAssesment.Api.SurveyResponses.Models +namespace DamageAssesment.Api.Responses.Models { public class Question { diff --git a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Models/Region.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Models/Region.cs similarity index 80% rename from DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Models/Region.cs rename to DamageAssesmentApi/DamageAssesment.Api.Responses/Models/Region.cs index 3fc5ad7..0f3ee9d 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Models/Region.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Models/Region.cs @@ -1,6 +1,6 @@ using System.ComponentModel.DataAnnotations; -namespace DamageAssesment.Api.SurveyResponses.Models +namespace DamageAssesment.Api.Responses.Models { public class Region { diff --git a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Models/Request.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Models/Request.cs similarity index 89% rename from DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Models/Request.cs rename to DamageAssesmentApi/DamageAssesment.Api.Responses/Models/Request.cs index 5060914..322314d 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Models/Request.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Models/Request.cs @@ -1,4 +1,4 @@ -namespace DamageAssesment.Api.SurveyResponses.Models +namespace DamageAssesment.Api.Responses.Models { public class Request { diff --git a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Models/Survey.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Models/Survey.cs similarity index 87% rename from DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Models/Survey.cs rename to DamageAssesmentApi/DamageAssesment.Api.Responses/Models/Survey.cs index b47193e..8265046 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Models/Survey.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Models/Survey.cs @@ -1,6 +1,6 @@ using System.ComponentModel.DataAnnotations; -namespace DamageAssesment.Api.SurveyResponses.Models +namespace DamageAssesment.Api.Responses.Models { public class Survey { diff --git a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Models/SurveyQuestion.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Models/SurveyQuestion.cs similarity index 81% rename from DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Models/SurveyQuestion.cs rename to DamageAssesmentApi/DamageAssesment.Api.Responses/Models/SurveyQuestion.cs index d510b4e..da3668f 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Models/SurveyQuestion.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Models/SurveyQuestion.cs @@ -1,4 +1,4 @@ -namespace DamageAssesment.Api.SurveyResponses.Models +namespace DamageAssesment.Api.Responses.Models { public class SurveyQuestions { diff --git a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Models/SurveyResponse.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Models/SurveyResponse.cs similarity index 91% rename from DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Models/SurveyResponse.cs rename to DamageAssesmentApi/DamageAssesment.Api.Responses/Models/SurveyResponse.cs index 37862ca..56d2048 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Models/SurveyResponse.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Models/SurveyResponse.cs @@ -1,7 +1,7 @@ using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -namespace DamageAssesment.Api.SurveyResponses.Models +namespace DamageAssesment.Api.Responses.Models { public class SurveyResponse { diff --git a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Models/SurveyTranslation.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Models/SurveyTranslation.cs similarity index 72% rename from DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Models/SurveyTranslation.cs rename to DamageAssesmentApi/DamageAssesment.Api.Responses/Models/SurveyTranslation.cs index 29a1b7c..022172f 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Models/SurveyTranslation.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Models/SurveyTranslation.cs @@ -1,4 +1,4 @@ -namespace DamageAssesment.Api.SurveyResponses.Models +namespace DamageAssesment.Api.Responses.Models { public class SurveyTranslation { diff --git a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Profiles/SurveyResponsesProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Profiles/SurveyResponsesProvider.cs similarity index 82% rename from DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Profiles/SurveyResponsesProvider.cs rename to DamageAssesmentApi/DamageAssesment.Api.Responses/Profiles/SurveyResponsesProvider.cs index d7c65a0..8208db7 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Profiles/SurveyResponsesProvider.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Profiles/SurveyResponsesProvider.cs @@ -1,4 +1,4 @@ -namespace DamageAssesment.Api.SurveyResponses.Profiles +namespace DamageAssesment.Api.Responses.Profiles { public class SurveyResponsesProvider : AutoMapper.Profile { diff --git a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Program.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Program.cs similarity index 51% rename from DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Program.cs rename to DamageAssesmentApi/DamageAssesment.Api.Responses/Program.cs index 985f3ac..566205a 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Program.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Program.cs @@ -1,10 +1,14 @@ -using DamageAssesment.Api.SurveyResponses.Db; -using DamageAssesment.Api.SurveyResponses.Interfaces; -using DamageAssesment.Api.SurveyResponses.Services; -using DamageAssesment.Api.SurveyResponses.Providers; +using DamageAssesment.Api.Responses.Db; +using DamageAssesment.Api.Responses.Interfaces; +using DamageAssesment.Api.Responses.Services; +using DamageAssesment.Api.Responses.Providers; using Microsoft.EntityFrameworkCore; using Polly; using System.Reflection; +using Microsoft.OpenApi.Models; +using Microsoft.AspNetCore.Authentication.JwtBearer; +using Microsoft.IdentityModel.Tokens; +using System.Text; var builder = WebApplication.CreateBuilder(args); const int maxApiCallRetries = 3; @@ -14,6 +18,24 @@ const int intervalForCircuitBraker = 5; //5 seconds // Add services to the container. +var authkey = builder.Configuration.GetValue("JwtSettings:securitykey"); +builder.Services.AddAuthentication(item => +{ + item.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; + item.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; +}).AddJwtBearer(item => +{ + item.RequireHttpsMetadata = true; + item.SaveToken = true; + item.TokenValidationParameters = new TokenValidationParameters() + { + ValidateIssuerSigningKey = true, + IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(authkey)), + ValidateIssuer = false, + ValidateAudience = false, + ClockSkew = TimeSpan.Zero + }; +}); builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle @@ -26,6 +48,7 @@ builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); +builder.Services.AddHttpContextAccessor(); builder.Services.AddHttpClient(). AddTransientHttpErrorPolicy(policy => policy.WaitAndRetryAsync(maxApiCallRetries, _ => TimeSpan.FromSeconds(intervalToRetry))). @@ -35,12 +58,40 @@ builder.Services.AddHttpClient(). builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies()); builder.Services.AddEndpointsApiExplorer(); //builder.Services.AddSwaggerGen(); -builder.Services.AddSwaggerGen(c => + +builder.Services.AddSwaggerGen(options => { // Include XML comments from your assembly var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); - c.IncludeXmlComments(xmlPath); + options.IncludeXmlComments(xmlPath); + + OpenApiSecurityScheme securityDefinition = new OpenApiSecurityScheme() + { + Name = "Bearer", + BearerFormat = "JWT", + Scheme = "bearer", + Description = "Specify the authorization token.", + In = ParameterLocation.Header, + Type = SecuritySchemeType.Http, + }; + + options.AddSecurityDefinition("jwt_auth", securityDefinition); + + // Make sure swagger UI requires a Bearer token specified + OpenApiSecurityScheme securityScheme = new OpenApiSecurityScheme() + { + Reference = new OpenApiReference() + { + Id = "jwt_auth", + Type = ReferenceType.SecurityScheme + } + }; + OpenApiSecurityRequirement securityRequirements = new OpenApiSecurityRequirement() + { + {securityScheme, new string[] { }}, + }; + options.AddSecurityRequirement(securityRequirements); }); builder.Services.AddDbContext(option => { @@ -55,6 +106,7 @@ if (app.Environment.IsDevelopment()) app.UseSwaggerUI(); } +app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); diff --git a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Properties/launchSettings.json b/DamageAssesmentApi/DamageAssesment.Api.Responses/Properties/launchSettings.json similarity index 94% rename from DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Properties/launchSettings.json rename to DamageAssesmentApi/DamageAssesment.Api.Responses/Properties/launchSettings.json index 0d51b15..f43ced8 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Properties/launchSettings.json +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Properties/launchSettings.json @@ -9,7 +9,7 @@ } }, "profiles": { - "DamageAssesment.Api.SurveyResponses": { + "DamageAssesment.Api.Responses": { "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": true, diff --git a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Providers/SurveyResponsesProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Providers/SurveyResponsesProvider.cs similarity index 68% rename from DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Providers/SurveyResponsesProvider.cs rename to DamageAssesmentApi/DamageAssesment.Api.Responses/Providers/SurveyResponsesProvider.cs index 6506f6a..eaba58f 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Providers/SurveyResponsesProvider.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Providers/SurveyResponsesProvider.cs @@ -1,10 +1,10 @@ using AutoMapper; -using DamageAssesment.Api.SurveyResponses.Db; -using DamageAssesment.Api.SurveyResponses.Interfaces; -using DamageAssesment.Api.SurveyResponses.Models; +using DamageAssesment.Api.Responses.Db; +using DamageAssesment.Api.Responses.Interfaces; +using DamageAssesment.Api.Responses.Models; using Microsoft.EntityFrameworkCore; -namespace DamageAssesment.Api.SurveyResponses.Providers +namespace DamageAssesment.Api.Responses.Providers { public class SurveyResponsesProvider : ISurveysResponse { @@ -18,8 +18,10 @@ namespace DamageAssesment.Api.SurveyResponses.Providers private readonly IQuestionServiceProvider questionServiceProvider; private readonly ISurveyServiceProvider surveyServiceProvider; private readonly IMapper mapper; + private readonly IHttpContextAccessor httpContextAccessor; + private string token; - public SurveyResponsesProvider(SurveyResponseDbContext surveyResponseDbContext, ILogger logger, IAnswerServiceProvider answerServiceProvider, IRegionServiceProvider regionServiceProvider, ILocationServiceProvider locationServiceProvider, IEmployeeServiceProvider employeeServiceProvider, IAttachmentServiceProvider attachmentServiceProvider, IQuestionServiceProvider questionServiceProvider, ISurveyServiceProvider surveyServiceProvider, IMapper mapper) + public SurveyResponsesProvider(SurveyResponseDbContext surveyResponseDbContext, ILogger logger, IAnswerServiceProvider answerServiceProvider, IRegionServiceProvider regionServiceProvider, ILocationServiceProvider locationServiceProvider, IEmployeeServiceProvider employeeServiceProvider, IAttachmentServiceProvider attachmentServiceProvider, IQuestionServiceProvider questionServiceProvider, ISurveyServiceProvider surveyServiceProvider, IMapper mapper, IHttpContextAccessor httpContextAccessor) { this.surveyResponseDbContext = surveyResponseDbContext; this.logger = logger; @@ -30,7 +32,18 @@ namespace DamageAssesment.Api.SurveyResponses.Providers this.attachmentServiceProvider = attachmentServiceProvider; this.questionServiceProvider = questionServiceProvider; this.surveyServiceProvider = surveyServiceProvider; + this.httpContextAccessor = httpContextAccessor; this.mapper = mapper; + + token = httpContextAccessor.HttpContext.Request.Headers.Authorization; + if (token != null) + { + token = token.Replace("Bearer ", string.Empty); + } + else + { + token = ""; + } // seedData(); } @@ -38,31 +51,22 @@ namespace DamageAssesment.Api.SurveyResponses.Providers { if (!surveyResponseDbContext.SurveyResponses.Any()) { - surveyResponseDbContext.SurveyResponses.Add(new Db.SurveyResponse { SurveyId = 1, EmployeeId = 1, LocationId = 1 }); - surveyResponseDbContext.SurveyResponses.Add(new Db.SurveyResponse { SurveyId = 1, EmployeeId = 2, LocationId = 1 }); - surveyResponseDbContext.SurveyResponses.Add(new Db.SurveyResponse { SurveyId = 3, EmployeeId = 3, LocationId = 2 }); - surveyResponseDbContext.SurveyResponses.Add(new Db.SurveyResponse { SurveyId = 4, EmployeeId = 4, LocationId = 2 }); - surveyResponseDbContext.SurveyResponses.Add(new Db.SurveyResponse { SurveyId = 1, EmployeeId = 5, LocationId = 3}); - surveyResponseDbContext.SurveyResponses.Add(new Db.SurveyResponse { SurveyId = 1, EmployeeId = 4, LocationId = 2 }); - surveyResponseDbContext.SurveyResponses.Add(new Db.SurveyResponse { SurveyId = 1, EmployeeId = 3, LocationId = 1 }); + surveyResponseDbContext.SurveyResponses.Add(new Db.SurveyResponse { Id = 1, SurveyId = 1, EmployeeId = 1, LocationId = 1, ClientDevice = "Mobile", Latitude = 98.8767, Longitute = -129.9897, KeyAnswerResult = "true", CreatedDate = DateTime.Now }); + surveyResponseDbContext.SurveyResponses.Add(new Db.SurveyResponse { Id = 2, SurveyId = 1, EmployeeId = 2, LocationId = 2, ClientDevice = "Desktop", Latitude = 98.8767, Longitute = -129.9897, KeyAnswerResult = "true", CreatedDate = DateTime.Now }); + surveyResponseDbContext.SurveyResponses.Add(new Db.SurveyResponse { Id = 3, SurveyId = 3, EmployeeId = 4, LocationId = 1, ClientDevice = "Mobile", Latitude = 98.8767, Longitute = -129.9897, KeyAnswerResult = "true", CreatedDate = DateTime.Now }); + surveyResponseDbContext.SurveyResponses.Add(new Db.SurveyResponse { Id = 4, SurveyId = 4, EmployeeId = 1, LocationId = 2, ClientDevice = "Desktop", Latitude = 98.8767, Longitute = -129.9897, KeyAnswerResult = "false", CreatedDate = DateTime.Now }); + surveyResponseDbContext.SurveyResponses.Add(new Db.SurveyResponse { Id = 5, SurveyId = 1, EmployeeId = 4, LocationId = 2, ClientDevice = "Desktop", Latitude = 98.8767, Longitute = -129.9897, KeyAnswerResult = "true", CreatedDate = DateTime.Now }); + surveyResponseDbContext.SurveyResponses.Add(new Db.SurveyResponse { Id = 6, SurveyId = 1, EmployeeId = 4, LocationId = 3, ClientDevice = "Desktop", Latitude = 98.8767, Longitute = -129.9897, KeyAnswerResult = "false", CreatedDate = DateTime.Now }); surveyResponseDbContext.SaveChanges(); } } - public async Task<(bool IsSuccess, dynamic Answers, string ErrorMessage)> GetAnswersByRegionAsync(int surveyId, int employeeid) + public async Task<(bool IsSuccess, dynamic Answers, string ErrorMessage)> GetAnswersByRegionAsync(int surveyId) { try { logger?.LogInformation("Querying to get SurveyResponse object from DB"); - IQueryable listSurveyResponse = null; - if (employeeid == 0) - { - listSurveyResponse = surveyResponseDbContext.SurveyResponses.Where(s => s.SurveyId == surveyId); - } - else - { - listSurveyResponse = surveyResponseDbContext.SurveyResponses.Where(s => s.SurveyId == surveyId && s.EmployeeId == employeeid); - } + var listSurveyResponse = surveyResponseDbContext.SurveyResponses.Where(s => s.SurveyId == surveyId); if (listSurveyResponse.Any()) { @@ -111,67 +115,19 @@ namespace DamageAssesment.Api.SurveyResponses.Providers return (false, null, ex.Message); } } - - public async Task<(bool IsSuccess, dynamic Surveys, string ErrorMessage)> GetActiveSurveysAsync(int employeeid, string language) - { - try - { - logger?.LogInformation("Querying to get SurveyResponse object from DB"); - //get all the survey that already taken by the employee - var listOfsurveysId = await surveyResponseDbContext.SurveyResponses.Where(x => x.EmployeeId == employeeid).Select(y => y.SurveyId).ToListAsync(); - var surveys = await surveyServiceProvider.getSurveysAsync(language); - if (surveys != null) - { - surveys = surveys.Where(s => s.IsEnabled == true && s.StartDate <= DateTime.Now && s.EndDate >= DateTime.Now).ToList(); - } - if (listOfsurveysId==null || listOfsurveysId.Count == 0) - return (true, surveys, null); - var activeSurveys = surveys.Where(s => s.IsEnabled == true && s.StartDate <= DateTime.Now && s.EndDate >= DateTime.Now && !listOfsurveysId.Contains(s.Id)); - return (true, activeSurveys, null); - } - catch (Exception ex) - { - logger?.LogError(ex.ToString()); - return (false, null, ex.Message); - } - } - - public async Task<(bool IsSuccess, dynamic Surveys, string ErrorMessage)> GetHistoricSurveysAsync(int employeeid, string language) - { - try - { - logger?.LogInformation("Querying to get SurveyResponse object from DB"); - //get all the survey that already taken by the employee - var surveyResponses = await surveyResponseDbContext.SurveyResponses.Where(x => x.EmployeeId == employeeid).ToListAsync(); - var surveys = await surveyServiceProvider.getSurveysAsync(language); - - var historicSurveys = from s in surveys - from r in surveyResponses - where s.Id == r.SurveyId - select s; - - return (true, historicSurveys, null); - } - catch (Exception ex) - { - logger?.LogError(ex.ToString()); - return (false, null, ex.Message); - } - } - - public async Task<(bool IsSuccess, dynamic SurveyResponses, string ErrorMessage)> GetSurveyResponsesBySurveyAsync(int surveyId, int employeeid) + public async Task<(bool IsSuccess, dynamic SurveyResponses, string ErrorMessage)> GetSurveyResponsesBySurveyAsync(int surveyId) { try { logger?.LogInformation("Querying to get Survey object from microservice"); - var survey = await surveyServiceProvider.getSurveyAsync(surveyId); + var survey = await surveyServiceProvider.getSurveyAsync(surveyId,token); if (survey != null) { - var answers = await getSurveyResponsesBySurveyIdAsync(surveyId, employeeid); + var answers = await getSurveyResponsesBySurveyIdAsync(surveyId); if (answers != null) return (true, answers, "Request Successful."); @@ -193,16 +149,16 @@ namespace DamageAssesment.Api.SurveyResponses.Providers } } - public async Task<(bool IsSuccess, dynamic SurveyResponses, string ErrorMessage)> GetSurveyResponsesBySurveyAndLocationAsync(int surveyId, int locationId, int employeeid) + public async Task<(bool IsSuccess, dynamic SurveyResponses, string ErrorMessage)> GetSurveyResponsesBySurveyAndLocationAsync(int surveyId, int locationId) { try { logger?.LogInformation("Querying to get Survey object from microservice"); - var survey = await surveyServiceProvider.getSurveyAsync(surveyId); + var survey = await surveyServiceProvider.getSurveyAsync(surveyId, token); if (survey != null) { - var answers = await getSurveyResponsesBySurveyIdLocationIdAsync(surveyId, locationId, employeeid); + var answers = await getSurveyResponsesBySurveyIdLocationIdAsync(surveyId, locationId); if (answers != null) return (true, answers, "Request Successful."); @@ -224,16 +180,16 @@ namespace DamageAssesment.Api.SurveyResponses.Providers } } - public async Task<(bool IsSuccess, dynamic SurveyResponses, string ErrorMessage)> GetSurveyResponsesByMaintenanceCenterAsync(int surveyId, int employeeid) + public async Task<(bool IsSuccess, dynamic SurveyResponses, string ErrorMessage)> GetSurveyResponsesByMaintenanceCenterAsync(int surveyId) { try { logger?.LogInformation("Querying to get Survey object from microservice"); - var survey = await surveyServiceProvider.getSurveyAsync(surveyId); + var survey = await surveyServiceProvider.getSurveyAsync(surveyId, token); if (survey != null) { - var answers = await getResultsByMaintenanceCenterAsync(surveyId, employeeid); + var answers = await getResultsByMaintenanceCenterAsync(surveyId); if (answers != null) return (true, answers, "Request Successful."); @@ -255,19 +211,19 @@ namespace DamageAssesment.Api.SurveyResponses.Providers } } - public async Task<(bool IsSuccess, dynamic SurveyResponses, string ErrorMessage)> GetResponsesByAnswerAsync(int surveyId, int questionId, string answer, int employeeid) + public async Task<(bool IsSuccess, dynamic SurveyResponses, string ErrorMessage)> GetResponsesByAnswerAsync(int surveyId, int questionId, string answer) { try { logger?.LogInformation("Querying to get Survey object from microservice"); - var survey = await surveyServiceProvider.getSurveyAsync(surveyId); - var question = await questionServiceProvider.getQuestionsAsync(questionId); + var survey = await surveyServiceProvider.getSurveyAsync(surveyId, token); + var question = await questionServiceProvider.getQuestionsAsync(questionId,token); bool IsCorrectAnswer = answer.ToLower().Equals("yes") || answer.ToLower().Equals("no") ? true : false; if (survey != null && question != null && IsCorrectAnswer) { - var answers = await getSurveyResponsesByAnswerAsync(survey, question, answer, employeeid); + var answers = await getSurveyResponsesByAnswerAsync(survey, question, answer); if (answers != null) return (true, answers, "Request Successful."); @@ -290,18 +246,18 @@ namespace DamageAssesment.Api.SurveyResponses.Providers } - public async Task<(bool IsSuccess, dynamic surveyResponses, string ErrorMessage)> GetSurveyResponsesAsync(int employeeid) + public async Task<(bool IsSuccess, dynamic surveyResponses, string ErrorMessage)> GetSurveyResponsesAsync() { try { - var responses = await getAllSurveyResponsesAsync(employeeid); + var answers = await getAllSurveyResponsesAsync(); - if (responses != null) - return (true, responses, "Request Successful."); + if (answers != null) + return (true, answers, "Request Successful."); else { - responses = new List(); - return (true, responses, "Empty object returned"); + answers = new List(); + return (true, answers, "Empty object returned"); } } catch (Exception ex) @@ -402,7 +358,7 @@ namespace DamageAssesment.Api.SurveyResponses.Providers { try { - var answersList = await answerServiceProvider.getAnswersAsync(); + var answersList = await answerServiceProvider.getAnswersAsync(token); if (answersList == null || !answersList.Any()) return null; @@ -412,7 +368,7 @@ namespace DamageAssesment.Api.SurveyResponses.Providers answer => answer.SurveyResponseId, surveyResponse => surveyResponse.Id, (answer, surveyResponse) => new - + { answer.Id, answer.QuestionId, @@ -425,8 +381,8 @@ namespace DamageAssesment.Api.SurveyResponses.Providers if (surveyAnswers == null || !surveyAnswers.Any()) return null; - var regions = await regionServiceProvider.getRegionsAsync(); - var locations = await locationServiceProvider.getLocationsAsync(); + var regions = await regionServiceProvider.getRegionsAsync(token); + var locations = await locationServiceProvider.getLocationsAsync(token); if (regions == null || !regions.Any() || locations == null || !locations.Any()) return null; @@ -436,18 +392,18 @@ namespace DamageAssesment.Api.SurveyResponses.Providers var result = from answer in surveyAnswers from location in locations where answer.LocationId.Equals(location.Id) - select new + select new { - answer.Id, - answer.QuestionId, - answer.AnswerText, - answer.Comment, - location.RegionId, - LocationId = location.Id, - answer.SurveyResponseId + answer.Id, + answer.QuestionId, + answer.AnswerText, + answer.Comment, + location.RegionId, + LocationId = location.Id, + answer.SurveyResponseId }; - + //group records by answer and region var q = from e in result @@ -455,13 +411,13 @@ namespace DamageAssesment.Api.SurveyResponses.Providers select new { g.Key.RegionId, - Answers = new + Answers = new { g.Key.AnswerText, Counter = g.Count() } }; - + //build the result List resultList = new List(); @@ -469,9 +425,9 @@ namespace DamageAssesment.Api.SurveyResponses.Providers { var answers = from u in q.ToList() where u.RegionId.Equals(region.Id) - select u.Answers; - - resultList.Add(new { RegionId = region.Id, region.Name, region.Abbreviation, Answers = answers }); + select u.Answers; + + resultList.Add(new { RegionId = region.Id, region.Name, region.Abbreviation, Answers = answers}); } //return the object result return new { Regions = resultList }; @@ -488,11 +444,11 @@ namespace DamageAssesment.Api.SurveyResponses.Providers { try { - var employee = await employeeServiceProvider.getEmployeeAsync(surveyResponse.EmployeeId); - var answers = await answerServiceProvider.GetAnswersByResponseIdAsync(surveyResponse.Id); - var allQuestions = await questionServiceProvider.getQuestionsAsync(); + var employee = await employeeServiceProvider.getEmployeeAsync(surveyResponse.EmployeeId, token); + var answers = await answerServiceProvider.GetAnswersByResponseIdAsync(surveyResponse.Id, token); + var allQuestions = await questionServiceProvider.getQuestionsAsync(token); var questions = allQuestions.Where(s => s.SurveyId == surveyResponse.SurveyId); - var attachments = await attachmentServiceProvider.getAttachmentsAsync(); + var attachments = await attachmentServiceProvider.getAttachmentsAsync(token); var result = new { @@ -527,95 +483,45 @@ namespace DamageAssesment.Api.SurveyResponses.Providers //Method to get Survey Responses by surveyId - private async Task getSurveyResponsesBySurveyIdAsync(int surveyId, int employeeid) + private async Task getSurveyResponsesBySurveyIdAsync(int surveyId) { try { - List surveyResonses = null; - Employee employee = null; - List employees = null; - if (employeeid == 0) - { - surveyResonses = await surveyResponseDbContext.SurveyResponses.Where(x => x.SurveyId == surveyId).ToListAsync(); - employees = await employeeServiceProvider.getEmployeesAsync(); - } - else - { - surveyResonses = await surveyResponseDbContext.SurveyResponses.Where(x => x.SurveyId == surveyId && x.EmployeeId == employeeid).ToListAsync(); - employee = await employeeServiceProvider.getEmployeeAsync(employeeid); - } - - var answers = await answerServiceProvider.getAnswersAsync(); - var questions = await questionServiceProvider.getQuestionsAsync(); + var surveyResonses = await surveyResponseDbContext.SurveyResponses.Where(x => x.SurveyId == surveyId).ToListAsync(); + var employees = await employeeServiceProvider.getEmployeesAsync(token); + var answers = await answerServiceProvider.getAnswersAsync(token); + var questions = await questionServiceProvider.getQuestionsAsync(token); var surveyQuestions = from q in questions where q.SurveyId == surveyId select q; //var surveyQuestions = await questionServiceProvider.getSurveyQuestionsAsync(surveyId); - var attachments = await attachmentServiceProvider.getAttachmentsAsync(); + var attachments = await attachmentServiceProvider.getAttachmentsAsync(token); + var result = from r in surveyResonses + select new + { + r.Id, + r.SurveyId, + r.LocationId, + r.EmployeeId, + r.ClientDevice, + r.KeyAnswerResult, + r.Longitute, + r.Latitude, + Employee = (from e in employees where e.Id == r.EmployeeId select new { e.Id, e.Name, e.BirthDate, e.Email, e.OfficePhoneNumber }).SingleOrDefault(), + answers = from ans in answers + where ans.SurveyResponseId == r.Id + select new + { + ans.Id, + ans.QuestionId, + ans.AnswerText, + ans.Comment, + Questions = (from q in surveyQuestions where q.Id == ans.QuestionId select new { q.Id, q.QuestionNumber, q.CategoryId, q.Text }).SingleOrDefault(), + Attachments = from att in attachments where att.AnswerId == ans.Id select new { att.Id, att.URI } - if (employeeid == 0) - { - var result = from r in surveyResonses - select new - { - r.Id, - r.SurveyId, - r.LocationId, - r.EmployeeId, - r.ClientDevice, - r.KeyAnswerResult, - r.Longitute, - r.Latitude, - Employee = (from e in employees where e.Id == r.EmployeeId select new { e.Id, e.Name, e.BirthDate, e.Email, e.OfficePhoneNumber }).SingleOrDefault(), - answers = from ans in answers - where ans.SurveyResponseId == r.Id - select new - { - ans.Id, - ans.QuestionId, - ans.AnswerText, - ans.Comment, - Questions = (from q in surveyQuestions where q.Id == ans.QuestionId select new { q.Id, q.QuestionNumber, q.CategoryId, q.Text }).SingleOrDefault(), - Attachments = from att in attachments where att.AnswerId == ans.Id select new { att.Id, att.URI } - - } - }; - return result; - } - else - { - object _employee = new { }; - if (employee != null) - { - _employee = new { employee.Id, employee.Name, employee.BirthDate, employee.Email, employee.OfficePhoneNumber }; - } - var result = from r in surveyResonses - select new - { - r.Id, - r.SurveyId, - r.LocationId, - r.EmployeeId, - r.ClientDevice, - r.KeyAnswerResult, - r.Longitute, - r.Latitude, - Employee = _employee, - answers = from ans in answers - where ans.SurveyResponseId == r.Id - select new - { - ans.Id, - ans.QuestionId, - ans.AnswerText, - ans.Comment, - Questions = (from q in questions where q.Id == ans.QuestionId select new { q.Id, q.QuestionNumber, q.CategoryId, q.Text }).SingleOrDefault(), - Attachments = from att in attachments where att.AnswerId == ans.Id select new { att.Id, att.URI } - } - }; - - return result; - } + } + }; + return result; } catch (Exception ex) { @@ -626,34 +532,15 @@ namespace DamageAssesment.Api.SurveyResponses.Providers //Method to get All Survey Responses - private async Task getAllSurveyResponsesAsync(int employeeid) + private async Task getAllSurveyResponsesAsync() { try { - List surveyResonses = null; - Employee employee = null; - List employees = null; - object _employee = new { }; - if (employeeid == 0) - { - surveyResonses = await surveyResponseDbContext.SurveyResponses.ToListAsync(); - employees = await employeeServiceProvider.getEmployeesAsync(); - } - else - { - surveyResonses = await surveyResponseDbContext.SurveyResponses.Where(x => x.EmployeeId == employeeid).ToListAsync(); - employee = await employeeServiceProvider.getEmployeeAsync(employeeid); - - if (employee != null) - { - _employee = new { employee.Id, employee.Name, employee.BirthDate, employee.Email, employee.OfficePhoneNumber }; - } - } - - - var answers = await answerServiceProvider.getAnswersAsync(); - var questions = await questionServiceProvider.getQuestionsAsync(); - var attachments = await attachmentServiceProvider.getAttachmentsAsync(); + var surveyResonses = await surveyResponseDbContext.SurveyResponses.ToListAsync(); + var employees = await employeeServiceProvider.getEmployeesAsync(token); + var answers = await answerServiceProvider.getAnswersAsync(token); + var questions = await questionServiceProvider.getQuestionsAsync(token); + var attachments = await attachmentServiceProvider.getAttachmentsAsync(token); var result = from r in surveyResonses select new @@ -666,7 +553,7 @@ namespace DamageAssesment.Api.SurveyResponses.Providers r.KeyAnswerResult, r.Longitute, r.Latitude, - Employee = employeeid != 0 ? _employee : (from e in employees where r.EmployeeId == e.Id select new { e.Id, e.Name, e.BirthDate, e.Email, e.OfficePhoneNumber }).SingleOrDefault(), + Employee = (from e in employees where r.EmployeeId == e.Id select new { e.Id, e.Name, e.BirthDate, e.Email, e.OfficePhoneNumber }).SingleOrDefault(), answers = from ans in answers where ans.SurveyResponseId == r.Id select new @@ -680,8 +567,6 @@ namespace DamageAssesment.Api.SurveyResponses.Providers } }; return result; - - } catch (Exception ex) { @@ -692,21 +577,13 @@ namespace DamageAssesment.Api.SurveyResponses.Providers //Method to get Answers By Maintenance Center by surveyId - private async Task getResultsByMaintenanceCenterAsync(int surveyId, int employeeid) + private async Task getResultsByMaintenanceCenterAsync(int surveyId) { try { - List surveyResponses = null; - if (employeeid == 0) - { - surveyResponses = await surveyResponseDbContext.SurveyResponses.Where(x => x.SurveyId == surveyId).ToListAsync(); - } - else - { - surveyResponses = await surveyResponseDbContext.SurveyResponses.Where(x => x.SurveyId == surveyId && x.EmployeeId == employeeid).ToListAsync(); - } - var answers = await answerServiceProvider.getAnswersAsync(); - var locations = await locationServiceProvider.getLocationsAsync(); + var surveyResponses = await surveyResponseDbContext.SurveyResponses.Where(x => x.SurveyId == surveyId).ToListAsync(); + var answers = await answerServiceProvider.getAnswersAsync(token); + var locations = await locationServiceProvider.getLocationsAsync(token); var maintenanceCenters = locations.DistinctBy(m => m.MaintenanceCenter); //get all the answers for the particular survey @@ -735,7 +612,7 @@ namespace DamageAssesment.Api.SurveyResponses.Providers select new { g.Key.MaintenanceCenter, - Answers = new + Answers = new { g.Key.AnswerText, Counter = g.Count() @@ -760,35 +637,16 @@ namespace DamageAssesment.Api.SurveyResponses.Providers } //Method to get Survey Responses by surveyId and LocationId - private async Task getSurveyResponsesBySurveyIdLocationIdAsync(int surveyId, int locationId, int employeeid) + private async Task getSurveyResponsesBySurveyIdLocationIdAsync(int surveyId, int locationId) { try { - List surveyResonses = null; - Employee employee = null; - List employees = null; - object _employee = new { }; - - if (employeeid == 0) - { - surveyResonses = await surveyResponseDbContext.SurveyResponses.Where(x => x.SurveyId == surveyId && x.LocationId == locationId).ToListAsync(); - employees = await employeeServiceProvider.getEmployeesAsync(); - } - else - { - surveyResonses = await surveyResponseDbContext.SurveyResponses.Where(x => x.SurveyId == surveyId && x.EmployeeId == employeeid && x.LocationId == locationId).ToListAsync(); - employee = await employeeServiceProvider.getEmployeeAsync(employeeid); - - if (employee != null) - { - _employee = new { employee.Id, employee.Name, employee.BirthDate, employee.Email, employee.OfficePhoneNumber }; - } - } - - var answers = await answerServiceProvider.getAnswersAsync(); - var questions = await questionServiceProvider.getQuestionsAsync(); + var surveyResonses = await surveyResponseDbContext.SurveyResponses.Where(x => x.SurveyId == surveyId && x.LocationId.Equals(locationId)).ToListAsync(); + var employees = await employeeServiceProvider.getEmployeesAsync(token); + var answers = await answerServiceProvider.getAnswersAsync(token); + var questions = await questionServiceProvider.getQuestionsAsync(token); var surveyQuestions = from q in questions where q.SurveyId == surveyId select q; - var attachments = await attachmentServiceProvider.getAttachmentsAsync(); + var attachments = await attachmentServiceProvider.getAttachmentsAsync(token); var result = from r in surveyResonses select new @@ -801,7 +659,7 @@ namespace DamageAssesment.Api.SurveyResponses.Providers r.KeyAnswerResult, r.Longitute, r.Latitude, - Employee = employeeid != 0 ? _employee : (from e in employees where r.EmployeeId == e.Id select new { e.Id, e.Name, e.BirthDate, e.Email, e.OfficePhoneNumber }).SingleOrDefault(), + Employee = (from e in employees where r.EmployeeId == e.Id select new { e.Id, e.Name, e.BirthDate, e.Email, e.OfficePhoneNumber }).SingleOrDefault(), answers = from ans in answers where ans.SurveyResponseId == r.Id @@ -816,7 +674,6 @@ namespace DamageAssesment.Api.SurveyResponses.Providers } }; return result; - } catch (Exception ex) { @@ -827,35 +684,14 @@ namespace DamageAssesment.Api.SurveyResponses.Providers //Method to get Survey Responses by surveyId questionId and answer - private async Task getSurveyResponsesByAnswerAsync(Survey survey, Question question, string answer, int employeeid) + private async Task getSurveyResponsesByAnswerAsync(Survey survey, Question question, string answer) { try { - List surveyResponses = null; - Employee employee = null; - List employees = null; - object _employee = new { }; - - if (employeeid == 0) - { - surveyResponses = await surveyResponseDbContext.SurveyResponses.Where(x => x.SurveyId == survey.Id).ToListAsync(); - employees = await employeeServiceProvider.getEmployeesAsync(); - } - else - { - surveyResponses = await surveyResponseDbContext.SurveyResponses.Where(x => x.SurveyId == survey.Id && x.EmployeeId == employeeid).ToListAsync(); - employee = await employeeServiceProvider.getEmployeeAsync(employeeid); - - if (employee != null) - { - _employee = new { employee.Id, employee.Name, employee.BirthDate, employee.Email, employee.OfficePhoneNumber }; - } - } - - //var surveyResponses = await surveyResponseDbContext.SurveyResponses.Where(x => x.SurveyId == survey.Id).ToListAsync(); - // var employees = await employeeServiceProvider.getEmployeesAsync(); - var answers = await answerServiceProvider.getAnswersAsync(); - var attachments = await attachmentServiceProvider.getAttachmentsAsync(); + var surveyResponses = await surveyResponseDbContext.SurveyResponses.Where(x => x.SurveyId == survey.Id).ToListAsync(); + var answers = await answerServiceProvider.getAnswersAsync(token); + var employees = await employeeServiceProvider.getEmployeesAsync(token); + var attachments = await attachmentServiceProvider.getAttachmentsAsync(token); var result = from r in surveyResponses select new @@ -868,7 +704,7 @@ namespace DamageAssesment.Api.SurveyResponses.Providers r.KeyAnswerResult, r.Longitute, r.Latitude, - Employee = employeeid != 0 ? _employee : (from e in employees where r.EmployeeId == e.Id select new { e.Id, e.Name, e.BirthDate, e.Email, e.OfficePhoneNumber }).SingleOrDefault(), + Employee = (from e in employees where r.EmployeeId == e.Id select new { e.Id, e.Name, e.BirthDate, e.Email, e.OfficePhoneNumber }).SingleOrDefault(), answers = from ans in answers where ans.SurveyResponseId == r.Id && ans.QuestionId == question.Id @@ -898,12 +734,12 @@ namespace DamageAssesment.Api.SurveyResponses.Providers { if (answerRequest != null) { - var answer = await answerServiceProvider.PostAnswersAsync(new Models.Answer { QuestionId = answerRequest.QuestionId, AnswerText = answerRequest.AnswerText, Comment = answerRequest.Comment, SurveyResponseId = surveyResponseId }); + var answer = await answerServiceProvider.PostAnswersAsync(new Models.Answer { QuestionId = answerRequest.QuestionId, AnswerText = answerRequest.AnswerText, Comment = answerRequest.Comment, SurveyResponseId = surveyResponseId }, token); if (answer != null) { List listAnswerInfo = new List(); listAnswerInfo.Add(new AnswerInfo { AnswerId = answer.Id, postedFiles = answerRequest.PostedFiles }); - var attachments = attachmentServiceProvider.PostAttachmentsAsync(new AttachmentInfo { ResponseId = surveyResponseId, Answers = listAnswerInfo }); + var attachments = attachmentServiceProvider.PostAttachmentsAsync(new AttachmentInfo { ResponseId = surveyResponseId, Answers = listAnswerInfo }, token); string message = $"Answer for question {answerRequest.QuestionId} saved to the database"; logger?.LogInformation(message); @@ -924,14 +760,13 @@ namespace DamageAssesment.Api.SurveyResponses.Providers } } - public async Task<(bool IsSuccess, Models.SurveyResponse SurveyResponse, string ErrorMessage)> PostSurveyAnswersAsync(Models.Request request) { try { if (request != null) { - var response = await PostSurveyResponseAsync(new Models.SurveyResponse { SurveyId = request.SurveyId, EmployeeId = request.EmployeeId, LocationId = request.LocationId, ClientDevice = request.ClientDevice, KeyAnswerResult = request.KeyAnswerResult, Latitude = Convert.ToDouble(request.Latitude), Longitute = Convert.ToDouble(request.Longitute), CreatedDate = DateTime.Now }); + var response = await PostSurveyResponseAsync(new Models.SurveyResponse { SurveyId = request.SurveyId, EmployeeId = request.EmployeeId, LocationId = request.LocationId, ClientDevice = request.ClientDevice, KeyAnswerResult = request.KeyAnswerResult, Latitude = Convert.ToDouble(request.Latitude), Longitute = Convert.ToDouble(request.Longitute), CreatedDate=DateTime.Now }); if (response.IsSuccess) { var surveyResponse = response.SurveyResponse; diff --git a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Services/AnswerServiceProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Services/AnswerServiceProvider.cs similarity index 85% rename from DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Services/AnswerServiceProvider.cs rename to DamageAssesmentApi/DamageAssesment.Api.Responses/Services/AnswerServiceProvider.cs index 695ad3e..b550ff1 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Services/AnswerServiceProvider.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Services/AnswerServiceProvider.cs @@ -1,20 +1,21 @@ -using DamageAssesment.Api.SurveyResponses.Interfaces; -using DamageAssesment.Api.SurveyResponses.Models; +using DamageAssesment.Api.Responses.Interfaces; +using DamageAssesment.Api.Responses.Models; +using Microsoft.Extensions.Primitives; using Newtonsoft.Json; -namespace DamageAssesment.Api.SurveyResponses.Services +namespace DamageAssesment.Api.Responses.Services { public class AnswerServiceProvider : ServiceProviderBase, IAnswerServiceProvider { public AnswerServiceProvider(IConfiguration configuration, IHttpUtil httpUtil, ILogger logger) : base(configuration, httpUtil, logger, configuration.GetValue("RessourceSettings:Answer"), configuration.GetValue("EndPointSettings:AnswerUrlBase")) { } - public async Task> getAnswersAsync() + public async Task> getAnswersAsync(string token) { try { - var responseJsonString = await httpUtil.SendAsync(HttpMethod.Get, url, null); + var responseJsonString = await httpUtil.SendAsync(HttpMethod.Get, url, null, token); var answers = JsonConvert.DeserializeObject>(responseJsonString); if (answers == null || !answers.Any()) @@ -28,12 +29,12 @@ namespace DamageAssesment.Api.SurveyResponses.Services } } - public async Task> GetAnswersByResponseIdAsync(int responseId) + public async Task> GetAnswersByResponseIdAsync(int responseId, string token) { try { url = urlBase + string.Format(configuration.GetValue("RessourceSettings:AnswerByResponse"), responseId); - var responseJsonString = await httpUtil.SendAsync(HttpMethod.Get, url, null); + var responseJsonString = await httpUtil.SendAsync(HttpMethod.Get, url, null,token); var answers = JsonConvert.DeserializeObject>(responseJsonString); if (answers == null || !answers.Any()) @@ -47,12 +48,12 @@ namespace DamageAssesment.Api.SurveyResponses.Services } } - public async Task PostAnswersAsync(Answer answer) + public async Task PostAnswersAsync(Answer answer, string token ) { try { var requestJsonString = JsonConvert.SerializeObject(answer); - var responseJsonString = await httpUtil.SendAsync(HttpMethod.Post, url, requestJsonString); + var responseJsonString = await httpUtil.SendAsync(HttpMethod.Post, url, requestJsonString, token); var answers = JsonConvert.DeserializeObject(responseJsonString); if (answers == null) diff --git a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Services/AttachmentServiceProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Services/AttachmentServiceProvider.cs similarity index 87% rename from DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Services/AttachmentServiceProvider.cs rename to DamageAssesmentApi/DamageAssesment.Api.Responses/Services/AttachmentServiceProvider.cs index 120e60f..9ace258 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Services/AttachmentServiceProvider.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Services/AttachmentServiceProvider.cs @@ -1,8 +1,8 @@ -using DamageAssesment.Api.SurveyResponses.Interfaces; -using DamageAssesment.Api.SurveyResponses.Models; +using DamageAssesment.Api.Responses.Interfaces; +using DamageAssesment.Api.Responses.Models; using Newtonsoft.Json; -namespace DamageAssesment.Api.SurveyResponses.Services +namespace DamageAssesment.Api.Responses.Services { public class AttachmentServiceProvider : ServiceProviderBase, IAttachmentServiceProvider { @@ -10,11 +10,11 @@ namespace DamageAssesment.Api.SurveyResponses.Services { } - public async Task> getAttachmentsAsync() + public async Task> getAttachmentsAsync(string token) { try { - var responseJsonString = await httpUtil.SendAsync(HttpMethod.Get, url, null); + var responseJsonString = await httpUtil.SendAsync(HttpMethod.Get, url, null,token); var attachments = JsonConvert.DeserializeObject>(responseJsonString); if (attachments == null || !attachments.Any()) @@ -28,12 +28,12 @@ namespace DamageAssesment.Api.SurveyResponses.Services } } - public async Task> PostAttachmentsAsync(AttachmentInfo attachmentInfo) + public async Task> PostAttachmentsAsync(AttachmentInfo attachmentInfo, string token) { try { var requestJsonString = JsonConvert.SerializeObject(attachmentInfo); - var responseJsonString = await httpUtil.SendAsync(HttpMethod.Post, url, requestJsonString); + var responseJsonString = await httpUtil.SendAsync(HttpMethod.Post, url, requestJsonString, token); var attachments = JsonConvert.DeserializeObject>(responseJsonString); if (attachments == null) diff --git a/DamageAssesmentApi/DamageAssesment.Api.Responses/Services/EmployeeServiceProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Services/EmployeeServiceProvider.cs new file mode 100644 index 0000000..507fc18 --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Services/EmployeeServiceProvider.cs @@ -0,0 +1,51 @@ +using DamageAssesment.Api.Responses.Interfaces; +using DamageAssesment.Api.Responses.Models; +using Microsoft.AspNetCore.Mvc.Routing; +using Newtonsoft.Json; + +namespace DamageAssesment.Api.Responses.Services +{ + public class EmployeeServiceProvider : ServiceProviderBase, IEmployeeServiceProvider + { + public EmployeeServiceProvider(IConfiguration configuration, IHttpUtil httpUtil, ILogger logger) : base(configuration, httpUtil, logger, configuration.GetValue("RessourceSettings:Employee"), configuration.GetValue("EndPointSettings:EmployeeUrlBase")) + { + } + + public async Task> getEmployeesAsync(string token) + { + try + { + var responseJsonString = await httpUtil.SendAsync(HttpMethod.Get, url, null,token); + var employees = JsonConvert.DeserializeObject>(responseJsonString); + + if (employees == null || !employees.Any()) + return new List(); + else return employees; + } + catch (Exception ex) + { + logger?.LogError($"Exception Found : {ex.Message} - Ref: EmployeeServiceProvider.getEmployeesAsync()"); + return new List(); + } + } + + public async Task getEmployeeAsync(int employeeId, string token) + { + try + { + url = urlBase + string.Format(configuration.GetValue("RessourceSettings:EmployeeById"), employeeId); + var responseJsonString = await httpUtil.SendAsync(HttpMethod.Get, url, null, token); + var employee = JsonConvert.DeserializeObject(responseJsonString); + + if (employee == null) + return null; + else return employee; + } + catch (Exception ex) + { + logger?.LogError($"Exception Found : {ex.Message} - Ref: EmployeeServiceProvider.getEmployeeAsync()"); + return null; + } + } + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.Responses/Services/HttpUtil.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Services/HttpUtil.cs new file mode 100644 index 0000000..3f8ca2d --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Services/HttpUtil.cs @@ -0,0 +1,42 @@ +using DamageAssesment.Api.Responses.Interfaces; +using DamageAssesment.Api.Responses.Models; +using System.Net.Http.Headers; +using System.Text; + +namespace DamageAssesment.Api.Responses.Services +{ + public class HttpUtil : IHttpUtil + { + private readonly HttpClient httpClient; + private readonly ILogger logger; + + public HttpUtil(HttpClient httpClient, ILogger logger) + { + this.httpClient = httpClient; + this.logger = logger; + } + public async Task SendAsync(HttpMethod method, string url, string JsonInput, string token) + { + try + { + var request = new HttpRequestMessage(method, url); + request.Headers.Accept.Clear(); + request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); + request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token); + if (method == HttpMethod.Post) + { + request.Content = new StringContent(JsonInput, Encoding.UTF8, "application/json"); + } + var response = await httpClient.SendAsync(request, CancellationToken.None); + response.EnsureSuccessStatusCode(); + var responseString = await response.Content.ReadAsStringAsync(); + return responseString; + } + catch (Exception ex) + { + logger?.LogError($"Exception Message : {ex.Message} - Ref: HttpUtil.SendAsync()"); + return null; + } + } + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Services/LocationServiceProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Services/LocationServiceProvider.cs similarity index 80% rename from DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Services/LocationServiceProvider.cs rename to DamageAssesmentApi/DamageAssesment.Api.Responses/Services/LocationServiceProvider.cs index 2e3fa32..2d38ca3 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Services/LocationServiceProvider.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Services/LocationServiceProvider.cs @@ -1,8 +1,8 @@ -using DamageAssesment.Api.SurveyResponses.Interfaces; -using DamageAssesment.Api.SurveyResponses.Models; +using DamageAssesment.Api.Responses.Interfaces; +using DamageAssesment.Api.Responses.Models; using Newtonsoft.Json; -namespace DamageAssesment.Api.SurveyResponses.Services +namespace DamageAssesment.Api.Responses.Services { public class LocationServiceProvider :ServiceProviderBase, ILocationServiceProvider { @@ -10,11 +10,11 @@ namespace DamageAssesment.Api.SurveyResponses.Services { } - public async Task> getLocationsAsync() + public async Task> getLocationsAsync(string token) { try { - var responseJsonString = await httpUtil.SendAsync(HttpMethod.Get, url, null); + var responseJsonString = await httpUtil.SendAsync(HttpMethod.Get, url, null, token); var locations = JsonConvert.DeserializeObject>(responseJsonString); if (locations == null || !locations.Any()) diff --git a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Services/QuestionServiceProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Services/QuestionServiceProvider.cs similarity index 87% rename from DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Services/QuestionServiceProvider.cs rename to DamageAssesmentApi/DamageAssesment.Api.Responses/Services/QuestionServiceProvider.cs index 138011f..4f2e75f 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Services/QuestionServiceProvider.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Services/QuestionServiceProvider.cs @@ -1,8 +1,8 @@ -using DamageAssesment.Api.SurveyResponses.Interfaces; -using DamageAssesment.Api.SurveyResponses.Models; +using DamageAssesment.Api.Responses.Interfaces; +using DamageAssesment.Api.Responses.Models; using Newtonsoft.Json; -namespace DamageAssesment.Api.SurveyResponses.Services +namespace DamageAssesment.Api.Responses.Services { public class QuestionServiceProvider : ServiceProviderBase, IQuestionServiceProvider { @@ -10,11 +10,11 @@ namespace DamageAssesment.Api.SurveyResponses.Services { } - public async Task> getQuestionsAsync() + public async Task> getQuestionsAsync(string token) { try { - var responseJsonString = await httpUtil.SendAsync(HttpMethod.Get, url, null); + var responseJsonString = await httpUtil.SendAsync(HttpMethod.Get, url, null,token); var questions = JsonConvert.DeserializeObject>(responseJsonString); if (questions == null || !questions.Any()) @@ -28,12 +28,12 @@ namespace DamageAssesment.Api.SurveyResponses.Services } } - public async Task> getSurveyQuestionsAsync(int surveyId) + public async Task> getSurveyQuestionsAsync(int surveyId, string token) { try { url = urlBase + string.Format(configuration.GetValue("RessourceSettings:SurveyQuestion"), surveyId); - var responseJsonString = await httpUtil.SendAsync(HttpMethod.Get, url, null); + var responseJsonString = await httpUtil.SendAsync(HttpMethod.Get, url, null, token); var questions = JsonConvert.DeserializeObject>(responseJsonString); if (questions == null || !questions.Any()) @@ -48,12 +48,12 @@ namespace DamageAssesment.Api.SurveyResponses.Services } - public async Task getQuestionsAsync(int questionId) + public async Task getQuestionsAsync(int questionId, string token) { try { url = urlBase + string.Format(configuration.GetValue("RessourceSettings:QuestionById"), questionId); - var responseJsonString = await httpUtil.SendAsync(HttpMethod.Get, url, null); + var responseJsonString = await httpUtil.SendAsync(HttpMethod.Get, url, null, token); var question = JsonConvert.DeserializeObject(responseJsonString); if (question == null) diff --git a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Services/RegionServiceProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Services/RegionServiceProvider.cs similarity index 80% rename from DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Services/RegionServiceProvider.cs rename to DamageAssesmentApi/DamageAssesment.Api.Responses/Services/RegionServiceProvider.cs index 091512e..13de3d6 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Services/RegionServiceProvider.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Services/RegionServiceProvider.cs @@ -1,19 +1,19 @@ -using DamageAssesment.Api.SurveyResponses.Interfaces; -using DamageAssesment.Api.SurveyResponses.Models; +using DamageAssesment.Api.Responses.Interfaces; +using DamageAssesment.Api.Responses.Models; using Newtonsoft.Json; -namespace DamageAssesment.Api.SurveyResponses.Services +namespace DamageAssesment.Api.Responses.Services { public class RegionServiceProvider : ServiceProviderBase, IRegionServiceProvider { public RegionServiceProvider(IConfiguration configuration, IHttpUtil httpUtil, ILogger logger) : base(configuration, httpUtil, logger, configuration.GetValue("RessourceSettings:Region"), configuration.GetValue("EndPointSettings:LocationUrlBase")) { } - public async Task> getRegionsAsync() + public async Task> getRegionsAsync(string token) { try { - var responseJsonString = await httpUtil.SendAsync(HttpMethod.Get, url, null); + var responseJsonString = await httpUtil.SendAsync(HttpMethod.Get, url, null, token); var regions = JsonConvert.DeserializeObject>(responseJsonString); if (regions == null || !regions.Any()) diff --git a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Services/ServiceProviderBase.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Services/ServiceProviderBase.cs similarity index 86% rename from DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Services/ServiceProviderBase.cs rename to DamageAssesmentApi/DamageAssesment.Api.Responses/Services/ServiceProviderBase.cs index af1aa65..1196f5b 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Services/ServiceProviderBase.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Services/ServiceProviderBase.cs @@ -1,6 +1,6 @@ -using DamageAssesment.Api.SurveyResponses.Interfaces; +using DamageAssesment.Api.Responses.Interfaces; -namespace DamageAssesment.Api.SurveyResponses.Services +namespace DamageAssesment.Api.Responses.Services { public class ServiceProviderBase { diff --git a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Services/SurveyServiceProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Services/SurveyServiceProvider.cs similarity index 72% rename from DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Services/SurveyServiceProvider.cs rename to DamageAssesmentApi/DamageAssesment.Api.Responses/Services/SurveyServiceProvider.cs index 19c081a..2e9732e 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Services/SurveyServiceProvider.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Services/SurveyServiceProvider.cs @@ -1,22 +1,20 @@ -using DamageAssesment.Api.SurveyResponses.Interfaces; -using DamageAssesment.Api.SurveyResponses.Models; +using DamageAssesment.Api.Responses.Interfaces; +using DamageAssesment.Api.Responses.Models; using Newtonsoft.Json; -namespace DamageAssesment.Api.SurveyResponses.Services +namespace DamageAssesment.Api.Responses.Services { - public class SurveyServiceProvider : ServiceProviderBase, ISurveyServiceProvider + public class SurveyServiceProvider :ServiceProviderBase, ISurveyServiceProvider { public SurveyServiceProvider(IConfiguration configuration, IHttpUtil httpUtil, ILogger logger) : base(configuration, httpUtil, logger, configuration.GetValue("RessourceSettings:Survey"), configuration.GetValue("EndPointSettings:SurveyUrlBase")) { } - public async Task> getSurveysAsync(string language) + public async Task> getSurveysAsync(string token) { try { - if (!string.IsNullOrEmpty(language)) - url = url + "/" + language; - var responseJsonString = await httpUtil.SendAsync(HttpMethod.Get, url, null); + var responseJsonString = await httpUtil.SendAsync(HttpMethod.Get, url, null, token); var surveys = JsonConvert.DeserializeObject>(responseJsonString); if (surveys == null || !surveys.Any()) @@ -30,15 +28,15 @@ namespace DamageAssesment.Api.SurveyResponses.Services } } - public async Task getSurveyAsync(int surveyId) + public async Task getSurveyAsync(int surveyId, string token) { try { url = urlBase + string.Format(configuration.GetValue("RessourceSettings:SurveyById"), surveyId); - var responseJsonString = await httpUtil.SendAsync(HttpMethod.Get, url, null); + var responseJsonString = await httpUtil.SendAsync(HttpMethod.Get, url, null, token); var survey = JsonConvert.DeserializeObject(responseJsonString); - if (survey == null) + if (survey == null ) return null; else return survey; } diff --git a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/appsettings.Development.json b/DamageAssesmentApi/DamageAssesment.Api.Responses/appsettings.Development.json similarity index 100% rename from DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/appsettings.Development.json rename to DamageAssesmentApi/DamageAssesment.Api.Responses/appsettings.Development.json diff --git a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/appsettings.Production.json b/DamageAssesmentApi/DamageAssesment.Api.Responses/appsettings.Production.json similarity index 100% rename from DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/appsettings.Production.json rename to DamageAssesmentApi/DamageAssesment.Api.Responses/appsettings.Production.json diff --git a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/appsettings.Test.json b/DamageAssesmentApi/DamageAssesment.Api.Responses/appsettings.Test.json similarity index 100% rename from DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/appsettings.Test.json rename to DamageAssesmentApi/DamageAssesment.Api.Responses/appsettings.Test.json diff --git a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/appsettings.json b/DamageAssesmentApi/DamageAssesment.Api.Responses/appsettings.json similarity index 94% rename from DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/appsettings.json rename to DamageAssesmentApi/DamageAssesment.Api.Responses/appsettings.json index 45a8ae8..dfd0152 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/appsettings.json +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/appsettings.json @@ -6,6 +6,9 @@ } }, "AllowedHosts": "*", + "JwtSettings": { + "securitykey": "bWlhbWkgZGFkZSBzY2hvb2xzIHNlY3JldCBrZXk=" + }, //"ConnectionStrings": { // "SurveyResponseConnection": "Server=DESKTOP-OF5DPLQ\\SQLEXPRESS;Database=da_survey_dev;Trusted_Connection=True;TrustServerCertificate=True;" //}, diff --git a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Interfaces/IAnswerServiceProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Interfaces/IAnswerServiceProvider.cs deleted file mode 100644 index e947659..0000000 --- a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Interfaces/IAnswerServiceProvider.cs +++ /dev/null @@ -1,12 +0,0 @@ -using DamageAssesment.Api.SurveyResponses.Models; - -namespace DamageAssesment.Api.SurveyResponses.Interfaces -{ - public interface IAnswerServiceProvider - { - Task> getAnswersAsync(); - Task> GetAnswersByResponseIdAsync(int responseId); - - Task PostAnswersAsync(Models.Answer answer); - } -} diff --git a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Interfaces/IAttachmentServiceProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Interfaces/IAttachmentServiceProvider.cs deleted file mode 100644 index a20c91c..0000000 --- a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Interfaces/IAttachmentServiceProvider.cs +++ /dev/null @@ -1,10 +0,0 @@ -using DamageAssesment.Api.SurveyResponses.Models; - -namespace DamageAssesment.Api.SurveyResponses.Interfaces -{ - public interface IAttachmentServiceProvider - { - Task> getAttachmentsAsync(); - Task> PostAttachmentsAsync(Models.AttachmentInfo attachmentInfo); - } -} diff --git a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Interfaces/ILocationServiceProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Interfaces/ILocationServiceProvider.cs deleted file mode 100644 index 75db3f1..0000000 --- a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Interfaces/ILocationServiceProvider.cs +++ /dev/null @@ -1,9 +0,0 @@ -using DamageAssesment.Api.SurveyResponses.Models; - -namespace DamageAssesment.Api.SurveyResponses.Interfaces -{ - public interface ILocationServiceProvider - { - Task> getLocationsAsync(); - } -} diff --git a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Interfaces/IQuestionServiceProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Interfaces/IQuestionServiceProvider.cs deleted file mode 100644 index ab5f5ba..0000000 --- a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Interfaces/IQuestionServiceProvider.cs +++ /dev/null @@ -1,11 +0,0 @@ -using DamageAssesment.Api.SurveyResponses.Models; - -namespace DamageAssesment.Api.SurveyResponses.Interfaces -{ - public interface IQuestionServiceProvider - { - Task> getQuestionsAsync(); - Task> getSurveyQuestionsAsync(int surveyId); - Task getQuestionsAsync(int questionId); - } -} diff --git a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Interfaces/IRegionServiceProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Interfaces/IRegionServiceProvider.cs deleted file mode 100644 index 8aeb1f8..0000000 --- a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Interfaces/IRegionServiceProvider.cs +++ /dev/null @@ -1,9 +0,0 @@ -using DamageAssesment.Api.SurveyResponses.Models; - -namespace DamageAssesment.Api.SurveyResponses.Interfaces -{ - public interface IRegionServiceProvider - { - Task> getRegionsAsync(); - } -} diff --git a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Interfaces/ISurveyServiceProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Interfaces/ISurveyServiceProvider.cs deleted file mode 100644 index 2b01d16..0000000 --- a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Interfaces/ISurveyServiceProvider.cs +++ /dev/null @@ -1,10 +0,0 @@ -using DamageAssesment.Api.SurveyResponses.Models; - -namespace DamageAssesment.Api.SurveyResponses.Interfaces -{ - public interface ISurveyServiceProvider - { - Task> getSurveysAsync(string language); - Task getSurveyAsync(int surveyId); - } -} diff --git a/DamageAssesmentApi/DamageAssesment.Api.Surveys/Controllers/SurveysController.cs b/DamageAssesmentApi/DamageAssesment.Api.Surveys/Controllers/SurveysController.cs index 1821c2f..2500f8b 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Surveys/Controllers/SurveysController.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Surveys/Controllers/SurveysController.cs @@ -1,4 +1,5 @@ using DamageAssesment.Api.Surveys.Interfaces; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; namespace DamageAssesment.Api.Surveys.Controllers @@ -15,6 +16,7 @@ namespace DamageAssesment.Api.Surveys.Controllers /// /// GET request for retrieving surveys. /// + [Authorize(Roles ="admin,survey,user,report")] [Route("Surveys")] [Route("Surveys/{language:alpha}")] [HttpGet] @@ -31,6 +33,7 @@ namespace DamageAssesment.Api.Surveys.Controllers /// /// GET request for retrieving surveys by ID. /// + [Authorize(Roles = "admin,survey,user,report")] [Route("Surveys/{id:int}")] [Route("Surveys/{id:int}/{language:alpha}")] [HttpGet] @@ -46,6 +49,7 @@ namespace DamageAssesment.Api.Surveys.Controllers /// /// POST request for creating a new survey. /// + [Authorize(Roles = "admin,survey,user,report")] [HttpPost("Surveys")] public async Task PostSurveysAsync(Models.Survey survey) { @@ -59,6 +63,8 @@ namespace DamageAssesment.Api.Surveys.Controllers /// /// PUT request for updating an existing survey (surveyId,Updated Survey data). /// + + [Authorize(Roles = "admin,survey")] [HttpPut("Surveys/{id}")] public async Task PutSurveysAsync(int id, Models.Survey survey) { @@ -76,6 +82,7 @@ namespace DamageAssesment.Api.Surveys.Controllers /// /// DELETE request for deleting a survey by ID. /// + [Authorize(Roles = "admin,survey")] [HttpDelete("Surveys/{id}")] public async Task DeleteSurveysAsync(int id) { diff --git a/DamageAssesmentApi/DamageAssesment.Api.Surveys/Program.cs b/DamageAssesmentApi/DamageAssesment.Api.Surveys/Program.cs index 178b5fd..6d79d25 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Surveys/Program.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Surveys/Program.cs @@ -6,6 +6,7 @@ using Microsoft.EntityFrameworkCore; using Microsoft.IdentityModel.Tokens; using System.Text; using System.Reflection; +using Microsoft.OpenApi.Models; var builder = WebApplication.CreateBuilder(args); @@ -34,14 +35,44 @@ builder.Services.AddControllers(); builder.Services.AddScoped(); builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies()); builder.Services.AddEndpointsApiExplorer(); -//builder.Services.AddSwaggerGen(); -builder.Services.AddSwaggerGen(c => + +builder.Services.AddSwaggerGen(options => { // Include XML comments from your assembly var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); - c.IncludeXmlComments(xmlPath); + options.IncludeXmlComments(xmlPath); + + OpenApiSecurityScheme securityDefinition = new OpenApiSecurityScheme() + { + Name = "Bearer", + BearerFormat = "JWT", + Scheme = "bearer", + Description = "Specify the authorization token.", + In = ParameterLocation.Header, + Type = SecuritySchemeType.Http, + }; + + options.AddSecurityDefinition("jwt_auth", securityDefinition); + + // Make sure swagger UI requires a Bearer token specified + OpenApiSecurityScheme securityScheme = new OpenApiSecurityScheme() + { + Reference = new OpenApiReference() + { + Id = "jwt_auth", + Type = ReferenceType.SecurityScheme + } + }; + + OpenApiSecurityRequirement securityRequirements = new OpenApiSecurityRequirement() + { + {securityScheme, new string[] { }}, + }; + + options.AddSecurityRequirement(securityRequirements); }); + builder.Services.AddDbContext(option => { option.UseSqlServer("SurveyConnection"); diff --git a/DamageAssesmentApi/DamageAssesment.Api.UsersAccess.Test/DamageAssesment.Api.UsersAccess.Test.csproj b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess.Test/DamageAssesment.Api.UsersAccess.Test.csproj new file mode 100644 index 0000000..e655693 --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess.Test/DamageAssesment.Api.UsersAccess.Test.csproj @@ -0,0 +1,30 @@ + + + + net6.0 + enable + enable + + false + true + + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + diff --git a/DamageAssesmentApi/DamageAssesment.Api.UsersAccess.Test/MockData.cs b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess.Test/MockData.cs new file mode 100644 index 0000000..b25ec9a --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess.Test/MockData.cs @@ -0,0 +1,44 @@ +using DamageAssesment.Api.UsersAccess.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Xunit.Sdk; + +namespace DamageAssesment.Api.UsersAccess.Test +{ + public class MockData + { + public static async Task<(bool, Models.TokenResponse, string)> getTokenResponse(bool status, string message) + { + return (status, new Models.TokenResponse { jwttoken = "1234", refreshtoken = "12345" }, message); + } + + public static async Task<(bool, List, string)> getUsers(bool status, string message) + { + List users = new List(); + users.Add(new User { Id = 1, EmployeeCode = "Emp1", EmployeeId = 1, RoleId = 1, IsActive = true, CreateDate = DateTime.Now }); + users.Add(new User { Id = 2, EmployeeCode = "Emp2", EmployeeId = 2, RoleId = 1, IsActive = true, CreateDate = DateTime.Now }); + users.Add(new User { Id = 3, EmployeeCode = "Emp3", EmployeeId = 3, RoleId = 1, IsActive = true, CreateDate = DateTime.Now }); + return (status, users, message); + } + + public static async Task<(bool, User, string)> getUser(bool status, string message) + { + User user = getUsers(status, message).Result.Item2.FirstOrDefault(); + return (status, user, message); + } + + public static async Task<(bool, List, string)> getRoles(bool status, string message) + { + List roles = new List(); + roles.Add(new Role { Id = 1, Name = "Role 1" }); + roles.Add(new Role { Id = 2, Name = "Role 2" }); + roles.Add(new Role { Id = 3, Name = "Role 3" }); + + return (status, roles, message); + } + + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.UsersAccess.Test/UsersAccessTest.cs b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess.Test/UsersAccessTest.cs new file mode 100644 index 0000000..46165f3 --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess.Test/UsersAccessTest.cs @@ -0,0 +1,194 @@ +using DamageAssesment.Api.UsersAccess.Controllers; +using DamageAssesment.Api.UsersAccess.Interfaces; +using Microsoft.AspNetCore.Mvc; +using Moq; +using Xunit; + +namespace DamageAssesment.Api.UsersAccess.Test +{ + public class UsersAccessTest + { + private Mock mockService; + + public UsersAccessTest() + { + mockService = new Mock(); + } + [Fact(DisplayName = "Get Token - Ok case")] + public async Task GetTokenAsync_ShouldReturnStatusCode200() + { + var response = await MockData.getTokenResponse(true,null); + mockService.Setup(service => service.AuthenticateAsync("Emp1")).ReturnsAsync(response); + var controller = new UsersAccessController(mockService.Object); + var result = (OkObjectResult)await controller.AuthenticateAsync("Emp1"); + Assert.Equal(200, result.StatusCode); + } + + [Fact(DisplayName = "Get Token - Unauthorized case")] + public async Task GetTokenAsync_ShouldReturnStatusCode401() + { + var response = await MockData.getTokenResponse(false, null); + mockService.Setup(service => service.AuthenticateAsync("Emp1")).ReturnsAsync(response); + var controller = new UsersAccessController(mockService.Object); + var result = (UnauthorizedObjectResult)await controller.AuthenticateAsync("Emp1"); + Assert.Equal(401, result.StatusCode); + } + + + [Fact(DisplayName = "RefreshToken - Ok case")] + public async Task RefreshTokenAsync_ShouldReturnStatusCode200() + { + var response = await MockData.getTokenResponse(true, null); + mockService.Setup(service => service.RefreshTokenAsync(null)).ReturnsAsync(response); + var controller = new UsersAccessController(mockService.Object); + var result = (OkObjectResult)await controller.RefreshTokenAsync(null); + Assert.Equal(200, result.StatusCode); + } + + [Fact(DisplayName = "RefreshToken - Unauthorized case")] + public async Task RefreshTokenAsync_ShouldReturnStatusCode401() + { + var response = await MockData.getTokenResponse(false, null); + mockService.Setup(service => service.RefreshTokenAsync(null)).ReturnsAsync(response); + var controller = new UsersAccessController(mockService.Object); + var result = (UnauthorizedObjectResult)await controller.RefreshTokenAsync(null); + Assert.Equal(401, result.StatusCode); + } + + [Fact(DisplayName = "GetUsers - Ok case")] + public async Task GetUsersAsync_ShouldReturnStatusCode200() + { + var response = await MockData.getUsers(true, null); + mockService.Setup(service => service.GetUsersAsync()).ReturnsAsync(response); + var controller = new UsersAccessController(mockService.Object); + var result = (OkObjectResult)await controller.GetUsersAsync(); + Assert.Equal(200, result.StatusCode); + } + + [Fact(DisplayName = "GetUsers - NoContent case")] + public async Task GetUsersAsync_ShouldReturnStatusCode204() + { + var response = await MockData.getUsers(false, null); + mockService.Setup(service => service.GetUsersAsync()).ReturnsAsync(response); + var controller = new UsersAccessController(mockService.Object); + var result = (NoContentResult)await controller.GetUsersAsync(); + Assert.Equal(204, result.StatusCode); + } + + [Fact(DisplayName = "GetUser - Ok case")] + public async Task GetUserAsync_ShouldReturnStatusCode200() + { + var response = await MockData.getUser(true, null); + mockService.Setup(service => service.GetUsersAsync(1)).ReturnsAsync(response); + var controller = new UsersAccessController(mockService.Object); + var result = (OkObjectResult)await controller.GetUsersAsync(1); + Assert.Equal(200, result.StatusCode); + } + + [Fact(DisplayName = "GetUser - NotFound case")] + public async Task GetUserAsync_ShouldReturnStatusCode204() + { + var response = await MockData.getUser(false, null); + mockService.Setup(service => service.GetUsersAsync(1)).ReturnsAsync(response); + var controller = new UsersAccessController(mockService.Object); + var result = (NotFoundResult)await controller.GetUsersAsync(1); + Assert.Equal(404, result.StatusCode); + } + + [Fact(DisplayName = "GetRoles - Ok case")] + public async Task GetRolesAsync_ShouldReturnStatusCode200() + { + var response = await MockData.getRoles(true, null); + mockService.Setup(service => service.GetRolesAsync()).ReturnsAsync(response); + var controller = new UsersAccessController(mockService.Object); + var result = (OkObjectResult)await controller.GetRolesAsync(); + Assert.Equal(200, result.StatusCode); + } + + [Fact(DisplayName = "GetRoles - NoContent case")] + public async Task GetRolesAsync_ShouldReturnStatusCode204() + { + var response = await MockData.getRoles(false, null); + mockService.Setup(service => service.GetRolesAsync()).ReturnsAsync(response); + var controller = new UsersAccessController(mockService.Object); + var result = (NoContentResult)await controller.GetRolesAsync(); + Assert.Equal(204, result.StatusCode); + } + + [Fact(DisplayName = "PostUser - Ok case")] + public async Task PostUserAsync_ShouldReturnStatusCode200() + { + var response = await MockData.getUser(true, null); + var user = new Models.User { Id = 1, EmployeeCode = "Emp1", EmployeeId = 1, RoleId = 1, IsActive = true, CreateDate = DateTime.Now }; + mockService.Setup(service => service.PostUserAsync(user)).ReturnsAsync(response); + var controller = new UsersAccessController(mockService.Object); + var result = (OkObjectResult)await controller.PostUserAsync(user); + Assert.Equal(200, result.StatusCode); + } + + [Fact(DisplayName = "PostUser - Bad Request case")] + public async Task PostUserAsync_ShouldReturnStatusCode400() + { + var response = await MockData.getUser(false, null); + var user = new Models.User { Id = 1, EmployeeCode = "Emp1", EmployeeId = 1, RoleId = 1, IsActive = true, CreateDate = DateTime.Now }; + mockService.Setup(service => service.PostUserAsync(user)).ReturnsAsync(response); + var controller = new UsersAccessController(mockService.Object); + var result = (BadRequestObjectResult)await controller.PostUserAsync(user); + Assert.Equal(400, result.StatusCode); + } + + [Fact(DisplayName = "PutUser - Ok case")] + public async Task PutUserAsync_ShouldReturnStatusCode200() + { + var response = await MockData.getUser(true, null); + var user = new Models.User { Id = 1, EmployeeCode = "Emp1", EmployeeId = 1, RoleId = 1, IsActive = true, CreateDate = DateTime.Now }; + mockService.Setup(service => service.PutUserAsync(1,user)).ReturnsAsync(response); + var controller = new UsersAccessController(mockService.Object); + var result = (OkObjectResult)await controller.PutUserAsync(1,user); + Assert.Equal(200, result.StatusCode); + } + + [Fact(DisplayName = "PutUser - BadRequest case")] + public async Task PutUserAsync_ShouldReturnStatusCode400() + { + var response = await MockData.getUser(false, null); + var user = new Models.User { Id = 1, EmployeeCode = "Emp1", EmployeeId = 1, RoleId = 1, IsActive = true, CreateDate = DateTime.Now }; + mockService.Setup(service => service.PutUserAsync(1,user)).ReturnsAsync(response); + var controller = new UsersAccessController(mockService.Object); + var result = (BadRequestObjectResult)await controller.PutUserAsync(1,user); + Assert.Equal(400, result.StatusCode); + } + + [Fact(DisplayName = "PutUser - Not Found case")] + public async Task PutUserAsync_ShouldReturnStatusCode404() + { + var response = await MockData.getUser(false, "Not Found"); + var user = new Models.User { Id = 1, EmployeeCode = "Emp1", EmployeeId = 1, RoleId = 1, IsActive = true, CreateDate = DateTime.Now }; + mockService.Setup(service => service.PutUserAsync(1, user)).ReturnsAsync(response); + var controller = new UsersAccessController(mockService.Object); + var result = (NotFoundObjectResult)await controller.PutUserAsync(1,user); + Assert.Equal(404, result.StatusCode); + } + + + [Fact(DisplayName = "DeleteUser - Ok case")] + public async Task DeleteUserAsync_ShouldReturnStatusCode200() + { + var response = await MockData.getUser(true, null); + mockService.Setup(service => service.DeleteUserAsync(1)).ReturnsAsync(response); + var controller = new UsersAccessController(mockService.Object); + var result = (OkObjectResult)await controller.DeleteUserAsync(1); + Assert.Equal(200, result.StatusCode); + } + + [Fact(DisplayName = "DeleteUser - Not Found case")] + public async Task DeleteUserAsync_ShouldReturnStatusCode404() + { + var response = await MockData.getUser(false, "Not Found"); + mockService.Setup(service => service.DeleteUserAsync(1)).ReturnsAsync(response); + var controller = new UsersAccessController(mockService.Object); + var result = (NotFoundResult)await controller.DeleteUserAsync(1); + Assert.Equal(404, result.StatusCode); + } + } +} \ No newline at end of file diff --git a/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Controllers/UsersAccessController.cs b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Controllers/UsersAccessController.cs new file mode 100644 index 0000000..e0aae67 --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Controllers/UsersAccessController.cs @@ -0,0 +1,117 @@ +using DamageAssesment.Api.UsersAccess.Interfaces; +using DamageAssesment.Api.UsersAccess.Models; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; + +namespace DamageAssesment.Api.UsersAccess.Controllers +{ + [ApiController] + public class UsersAccessController : ControllerBase + { + private IUsersAccessProvider userAccessProvider; + + public UsersAccessController(IUsersAccessProvider userAccessProvider) + { + this.userAccessProvider = userAccessProvider; + } + [Authorize(Policy = "Dadeschools")] + [HttpPost("token/{employecode}")] + public async Task AuthenticateAsync(string employecode) + { + var result = await userAccessProvider.AuthenticateAsync(employecode); + if (result.IsSuccess) + { + return Ok(result.TokenResponse); + } + return Unauthorized(result.ErrorMessage); + } + + [Authorize(Policy = "Dadeschools")] + [HttpPost("refreshtoken")] + public async Task RefreshTokenAsync(TokenResponse tokenResponse) + { + var result = await userAccessProvider.RefreshTokenAsync(tokenResponse); + if (result.IsSuccess) + { + return Ok(result.TokenResponse); + } + return Unauthorized(result.ErrorMessage); + } + + [Authorize(Policy = "DamageApp", Roles ="admin")] + [HttpGet("users")] + public async Task GetUsersAsync() + { + var result = await userAccessProvider.GetUsersAsync(); + if (result.IsSuccess) + { + return Ok(result.Users); + } + return NoContent(); + } + + [Authorize(Policy = "DamageApp", Roles = "admin")] + [HttpGet("users/{Id}")] + public async Task GetUsersAsync(int Id) + { + var result = await userAccessProvider.GetUsersAsync(Id); + if (result.IsSuccess) + { + return Ok(result.User); + } + return NotFound(); + } + + [Authorize(Policy = "DamageApp", Roles = "admin")] + [HttpGet("roles")] + public async Task GetRolesAsync() + { + var result = await userAccessProvider.GetRolesAsync(); + if (result.IsSuccess) + { + return Ok(result.Roles); + } + return NoContent(); + } + [Authorize(Policy = "DamageApp", Roles = "admin")] + [HttpPost("users")] + public async Task PostUserAsync(User user) + { + var result = await userAccessProvider.PostUserAsync(user); + if (result.IsSuccess) + { + return Ok(result.User); + } + return BadRequest(result.ErrorMessage); + } + + [Authorize(Policy = "DamageApp", Roles = "admin")] + [HttpPut("users/{Id}")] + public async Task PutUserAsync(int Id, User user) + { + var result = await userAccessProvider.PutUserAsync(Id, user); + if (result.IsSuccess) + { + return Ok(result.User); + } + if (result.ErrorMessage == "Not Found") + return NotFound(result.ErrorMessage); + + return BadRequest(result.ErrorMessage); + } + + [Authorize(Policy = "DamageApp", Roles = "admin")] + [HttpDelete("users/{Id}")] + public async Task DeleteUserAsync(int Id) + { + var result = await userAccessProvider.DeleteUserAsync(Id); + if (result.IsSuccess) + { + return Ok(result.User); + } + return NotFound(); + } + + + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/DamageAssesment.Api.UsersAccess.csproj b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/DamageAssesment.Api.UsersAccess.csproj new file mode 100644 index 0000000..6c6eb21 --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/DamageAssesment.Api.UsersAccess.csproj @@ -0,0 +1,29 @@ + + + + net6.0 + enable + enable + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + diff --git a/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Db/Role.cs b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Db/Role.cs new file mode 100644 index 0000000..93e522a --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Db/Role.cs @@ -0,0 +1,21 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Text.Json.Serialization; + +namespace DamageAssesment.Api.UsersAccess.Db +{ + public class Role + { + [Key] + public int Id { get; set; } + + [StringLength(100)] + [Required] + public string Name { get; set; } + + // add a status field + + [StringLength(100)] + public string? Description { get; set; } + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Db/Token.cs b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Db/Token.cs new file mode 100644 index 0000000..bdfe576 --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Db/Token.cs @@ -0,0 +1,17 @@ +using Microsoft.EntityFrameworkCore.Metadata.Internal; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace DamageAssesment.Api.UsersAccess.Db +{ + public class Token + { + [Key] + public int Id { get; set; } + [Required] + [ForeignKey("User")] + public int UserId { get; set; } + public string? RefreshToken { get; set; } + public bool? IsActive { get; set; } + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Db/User.cs b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Db/User.cs new file mode 100644 index 0000000..f99deb8 --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Db/User.cs @@ -0,0 +1,31 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Text.Json.Serialization; + +namespace DamageAssesment.Api.UsersAccess.Db +{ + public class User + { + [Key] + public int Id { get; set; } + + [ForeignKey("Employee")] + public int EmployeeId { get; set; } + + [Required] + [StringLength(50)] + public string EmployeeCode { get; set; } + + [ForeignKey("Role")] + [Required] + public int RoleId { get; set; } + [Required] + public bool IsActive { get; set; } = true; + + [Required] + public DateTime CreateDate { get; set; } = DateTime.Now; + + public DateTime? UpdateDate { get; set; } + + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Db/UsersAccessDbContext.cs b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Db/UsersAccessDbContext.cs new file mode 100644 index 0000000..157dfb3 --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Db/UsersAccessDbContext.cs @@ -0,0 +1,39 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; + +namespace DamageAssesment.Api.UsersAccess.Db +{ + public class UsersAccessDbContext : DbContext + { + public DbSet Users { get; set; } + public DbSet Roles { get; set; } + public DbSet Tokens { get; set; } + private IConfiguration _Configuration { get; set; } + public UsersAccessDbContext(DbContextOptions options, IConfiguration configuration) : base(options) + { + _Configuration = configuration; + } + protected override void OnConfiguring(DbContextOptionsBuilder options) + { + // connect to sql server with connection string from app settings + options.UseSqlServer(_Configuration.GetConnectionString("UsersAccessConnection")); + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + + modelBuilder.Entity() + .Property(item => item.Id) + .ValueGeneratedOnAdd(); + + modelBuilder.Entity() + .Property(item => item.Id) + .ValueGeneratedOnAdd(); + + modelBuilder.Entity() + .Property(item => item.Id) + .ValueGeneratedOnAdd(); + } + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Interfaces/IEmployeeServiceProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Interfaces/IEmployeeServiceProvider.cs similarity index 60% rename from DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Interfaces/IEmployeeServiceProvider.cs rename to DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Interfaces/IEmployeeServiceProvider.cs index 62031d5..255a954 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Interfaces/IEmployeeServiceProvider.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Interfaces/IEmployeeServiceProvider.cs @@ -1,6 +1,6 @@ -using DamageAssesment.Api.SurveyResponses.Models; +using DamageAssesment.Api.UsersAccess.Models; -namespace DamageAssesment.Api.SurveyResponses.Interfaces +namespace DamageAssesment.Api.UsersAccess.Interfaces { public interface IEmployeeServiceProvider { diff --git a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Interfaces/IHttpUtil.cs b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Interfaces/IHttpUtil.cs similarity index 53% rename from DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Interfaces/IHttpUtil.cs rename to DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Interfaces/IHttpUtil.cs index e3f1e66..3d0a8ed 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Interfaces/IHttpUtil.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Interfaces/IHttpUtil.cs @@ -1,6 +1,4 @@ -using DamageAssesment.Api.SurveyResponses.Models; - -namespace DamageAssesment.Api.SurveyResponses.Interfaces +namespace DamageAssesment.Api.UsersAccess.Interfaces { public interface IHttpUtil { diff --git a/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Interfaces/IRoleProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Interfaces/IRoleProvider.cs new file mode 100644 index 0000000..6ca0209 --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Interfaces/IRoleProvider.cs @@ -0,0 +1,12 @@ +namespace DamageAssesment.Api.UsersAccess.Interfaces +{ + public interface IRoleProvider + { + Task<(bool IsSuccess, IEnumerable< Models.Role> Roles, string ErrorMessage)> GetRolesAsync(); + Task<(bool IsSuccess, Models.Role Roles, string ErrorMessage)> GetRolesAsync(int Id); + Task<(bool IsSuccess, Models.Role Role, string ErrorMessage)> PostRoleAsync(Models.Role Role); + Task<(bool IsSuccess, Models.Role Role, string ErrorMessage)> PutRoleAsync(int Id,Models.Role Role); + Task<(bool IsSuccess, Models.Role Role, string ErrorMessage)> DeleteRoleAsync(int Id); + + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Interfaces/ITokenServiceProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Interfaces/ITokenServiceProvider.cs new file mode 100644 index 0000000..6115e7c --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Interfaces/ITokenServiceProvider.cs @@ -0,0 +1,11 @@ +using DamageAssesment.Api.UsersAccess.Models; +using System.Security.Claims; + +namespace DamageAssesment.Api.UsersAccess.Interfaces +{ + public interface ITokenServiceProvider + { + Task GenerateToken(Models.User user); + Task TokenAuthenticate(Models.User user, Claim[] claims); + } +} \ No newline at end of file diff --git a/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Interfaces/IUsersAccessProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Interfaces/IUsersAccessProvider.cs new file mode 100644 index 0000000..ea64376 --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Interfaces/IUsersAccessProvider.cs @@ -0,0 +1,17 @@ +using DamageAssesment.Api.UsersAccess.Models; + +namespace DamageAssesment.Api.UsersAccess.Interfaces +{ + public interface IUsersAccessProvider + { + public Task<(bool IsSuccess, IEnumerable< Models.User> Users, string ErrorMessage)> GetUsersAsync(); + public Task<(bool IsSuccess, Models.User User, string ErrorMessage)> GetUsersAsync(int Id); + public Task<(bool IsSuccess, Models.User User, string ErrorMessage)> PostUserAsync(Models.User User); + public Task<(bool IsSuccess, Models.User User, string ErrorMessage)> PutUserAsync(int Id,Models.User User); + public Task<(bool IsSuccess, Models.User User, string ErrorMessage)> DeleteUserAsync(int Id); + public Task<(bool IsSuccess, IEnumerable Roles, string ErrorMessage)> GetRolesAsync(); + public Task<(bool IsSuccess, Models.TokenResponse TokenResponse, string ErrorMessage)> AuthenticateAsync(string employeCode); + public Task<(bool IsSuccess, Models.TokenResponse TokenResponse, string ErrorMessage)>RefreshTokenAsync(TokenResponse tokenResponse); + public void seedData(); + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Migrations/20230929161148_AzureUserAccess.Designer.cs b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Migrations/20230929161148_AzureUserAccess.Designer.cs new file mode 100644 index 0000000..81c55ec --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Migrations/20230929161148_AzureUserAccess.Designer.cs @@ -0,0 +1,107 @@ +// +using System; +using DamageAssesment.Api.UsersAccess.Db; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace DamageAssesment.Api.UsersAccess.Migrations +{ + [DbContext(typeof(UsersAccessDbContext))] + [Migration("20230929161148_AzureUserAccess")] + partial class AzureUserAccess + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.9") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("DamageAssesment.Api.UsersAccess.Db.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Description") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.HasKey("Id"); + + b.ToTable("Roles"); + }); + + modelBuilder.Entity("DamageAssesment.Api.UsersAccess.Db.Token", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("RefreshToken") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Tokens"); + }); + + modelBuilder.Entity("DamageAssesment.Api.UsersAccess.Db.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreateDate") + .HasColumnType("datetime2"); + + b.Property("EmployeeCode") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("EmployeeId") + .HasColumnType("int"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.Property("UpdateDate") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Migrations/20230929161148_AzureUserAccess.cs b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Migrations/20230929161148_AzureUserAccess.cs new file mode 100644 index 0000000..c5b4d8e --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Migrations/20230929161148_AzureUserAccess.cs @@ -0,0 +1,75 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace DamageAssesment.Api.UsersAccess.Migrations +{ + /// + public partial class AzureUserAccess : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Roles", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Name = table.Column(type: "nvarchar(100)", maxLength: 100, nullable: false), + Description = table.Column(type: "nvarchar(100)", maxLength: 100, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Roles", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Tokens", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + UserId = table.Column(type: "int", nullable: false), + RefreshToken = table.Column(type: "nvarchar(max)", nullable: true), + IsActive = table.Column(type: "bit", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Tokens", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Users", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + EmployeeId = table.Column(type: "int", nullable: false), + EmployeeCode = table.Column(type: "nvarchar(50)", maxLength: 50, nullable: false), + RoleId = table.Column(type: "int", nullable: false), + IsActive = table.Column(type: "bit", nullable: false), + CreateDate = table.Column(type: "datetime2", nullable: false), + UpdateDate = table.Column(type: "datetime2", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Users", x => x.Id); + }); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Roles"); + + migrationBuilder.DropTable( + name: "Tokens"); + + migrationBuilder.DropTable( + name: "Users"); + } + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Migrations/UsersAccessDbContextModelSnapshot.cs b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Migrations/UsersAccessDbContextModelSnapshot.cs new file mode 100644 index 0000000..adf97d5 --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Migrations/UsersAccessDbContextModelSnapshot.cs @@ -0,0 +1,104 @@ +// +using System; +using DamageAssesment.Api.UsersAccess.Db; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace DamageAssesment.Api.UsersAccess.Migrations +{ + [DbContext(typeof(UsersAccessDbContext))] + partial class UsersAccessDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.9") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("DamageAssesment.Api.UsersAccess.Db.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Description") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.HasKey("Id"); + + b.ToTable("Roles"); + }); + + modelBuilder.Entity("DamageAssesment.Api.UsersAccess.Db.Token", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("RefreshToken") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Tokens"); + }); + + modelBuilder.Entity("DamageAssesment.Api.UsersAccess.Db.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreateDate") + .HasColumnType("datetime2"); + + b.Property("EmployeeCode") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("EmployeeId") + .HasColumnType("int"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.Property("UpdateDate") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Models/Employee.cs b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Models/Employee.cs new file mode 100644 index 0000000..b08d156 --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Models/Employee.cs @@ -0,0 +1,14 @@ +namespace DamageAssesment.Api.UsersAccess.Models +{ + public class Employee + { + public int Id { get; set; } + public string EmployeeCode { get; set; } + public string Name { get; set; } + public DateTime BirthDate { get; set; } + public string OfficePhoneNumber { get; set; } + public string Email { get; set; } + public bool IsActive { get; set; } + public string PreferredLanguage { get; set; } + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Models/JwtSettings.cs b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Models/JwtSettings.cs new file mode 100644 index 0000000..3f9dadf --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Models/JwtSettings.cs @@ -0,0 +1,9 @@ +using System.ComponentModel.DataAnnotations; +namespace DamageAssesment.Api.UsersAccess.Models +{ + + public class JwtSettings + { + public string securitykey { get; set; } + } +} \ No newline at end of file diff --git a/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Models/Role.cs b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Models/Role.cs new file mode 100644 index 0000000..a275c60 --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Models/Role.cs @@ -0,0 +1,8 @@ +namespace DamageAssesment.Api.UsersAccess.Models +{ + public class Role { + public int Id { get; set; } + public string Name { get; set; } + public string Description { get; set; } + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Models/Token.cs b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Models/Token.cs new file mode 100644 index 0000000..87f1ae3 --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Models/Token.cs @@ -0,0 +1,10 @@ +namespace DamageAssesment.Api.UsersAccess.Models +{ + public class Token + { + public string Id { get; set; } + public int UserId { get; set; } + public string RefreshToken { get; set; } + public bool IsActive { get; set; } + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Models/TokenResponse.cs b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Models/TokenResponse.cs new file mode 100644 index 0000000..4d0b6da --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Models/TokenResponse.cs @@ -0,0 +1,8 @@ +namespace DamageAssesment.Api.UsersAccess.Models +{ + public class TokenResponse + { + public string? jwttoken { get; set; } + public string? refreshtoken { get; set; } + } +} \ No newline at end of file diff --git a/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Models/User.cs b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Models/User.cs new file mode 100644 index 0000000..e43bc20 --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Models/User.cs @@ -0,0 +1,13 @@ +namespace DamageAssesment.Api.UsersAccess.Models +{ + public class User + { + public int Id { get; set; } + public int EmployeeId { get; set; } + public string EmployeeCode { get; set; } + public int RoleId { get; set; } + public bool IsActive { get; set; } + public DateTime CreateDate { get; set; } + public DateTime UpdateDate { get; set; } + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Models/UserCredentials.cs b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Models/UserCredentials.cs new file mode 100644 index 0000000..cf01fa3 --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Models/UserCredentials.cs @@ -0,0 +1,5 @@ +public class UserCredentials +{ + public string username { get; set; } + // public string? password { get; set; } +} \ No newline at end of file diff --git a/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Profiles/UsersAccessProfile.cs b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Profiles/UsersAccessProfile.cs new file mode 100644 index 0000000..bf744eb --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Profiles/UsersAccessProfile.cs @@ -0,0 +1,14 @@ +namespace DamageAssesment.Api.UsersAccess.Profiles +{ + public class UsersAccessProfile : AutoMapper.Profile + { + public UsersAccessProfile() + { + CreateMap(); + CreateMap(); + + CreateMap(); + CreateMap(); + } + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Program.cs b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Program.cs new file mode 100644 index 0000000..567e613 --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Program.cs @@ -0,0 +1,146 @@ +using DamageAssesment.Api.UsersAccess.Db; +using DamageAssesment.Api.UsersAccess.Interfaces; +using DamageAssesment.Api.UsersAccess.Providers; +using DamageAssesment.Api.UsersAccess.Models; +using Microsoft.EntityFrameworkCore; +using Microsoft.IdentityModel.Tokens; +using System.Text; +using Polly; +using DamageAssesment.Api.UsersAccess.Services; +using Microsoft.OpenApi.Models; +using System.Reflection; +using Microsoft.AspNetCore.Authorization; + +const int maxApiCallRetries = 3; +const int intervalToRetry = 2; //2 seconds +const int maxRetryForCircuitBraker = 5; +const int intervalForCircuitBraker = 5; //5 seconds + +var builder = WebApplication.CreateBuilder(args); + +// Add services to the container. +var authkey = builder.Configuration.GetValue("JwtSettings:securitykey"); + + +builder.Services.AddAuthentication(). + AddJwtBearer("DamageApp", item => +{ + + item.RequireHttpsMetadata = true; + item.SaveToken = true; + item.TokenValidationParameters = new TokenValidationParameters() + { + ValidateIssuerSigningKey = true, + IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(authkey)), + ValidateIssuer = false, + ValidateAudience = false, + ClockSkew = TimeSpan.Zero + }; +}).AddJwtBearer("Dadeschools", options => +{ + options.Authority = builder.Configuration["Dadeschools:Authority"]; + options.TokenValidationParameters.ValidTypes = new[] { "at+jwt" }; + options.TokenValidationParameters.ValidateAudience = false; +}); + + +builder.Services.AddAuthorization(options => +{ + var DamageAppPolicy = new AuthorizationPolicyBuilder() + .RequireAuthenticatedUser() + .AddAuthenticationSchemes("DamageApp") + .Build(); + var DadeschoolsPolicy = new AuthorizationPolicyBuilder() + .RequireAuthenticatedUser() + .AddAuthenticationSchemes("Dadeschools") + .Build(); + var allPolicy = new AuthorizationPolicyBuilder() + .RequireAuthenticatedUser() + .AddAuthenticationSchemes("DamageApp", "Dadeschools") + .Build(); + options.AddPolicy("DamageApp", DamageAppPolicy); + options.AddPolicy("Dadeschools", DadeschoolsPolicy); + options.AddPolicy("AllPolicies", allPolicy); + options.DefaultPolicy = options.GetPolicy("DamageApp")!; +}); + +var _jwtsettings = builder.Configuration.GetSection("JwtSettings"); +builder.Services.Configure(_jwtsettings); + +builder.Services.AddControllers(); +// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); + +builder.Services.AddHttpClient(). + AddTransientHttpErrorPolicy(policy => policy.WaitAndRetryAsync(maxApiCallRetries, _ => TimeSpan.FromSeconds(intervalToRetry))). + AddTransientHttpErrorPolicy(policy => policy.CircuitBreakerAsync(maxRetryForCircuitBraker, TimeSpan.FromSeconds(intervalForCircuitBraker))); + +builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies()); +builder.Services.AddEndpointsApiExplorer(); +//builder.Services.AddSwaggerGen(); + +builder.Services.AddSwaggerGen(options => +{ + + // Include XML comments from your assembly + var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; + var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); + //options.IncludeXmlComments(xmlPath); + + OpenApiSecurityScheme securityDefinition = new OpenApiSecurityScheme() + { + Name = "Bearer", + BearerFormat = "JWT", + Scheme = "bearer", + Description = "Specify the authorization token.", + In = ParameterLocation.Header, + Type = SecuritySchemeType.Http, + }; + + options.AddSecurityDefinition("jwt_auth", securityDefinition); + + // Make sure swagger UI requires a Bearer token specified + OpenApiSecurityScheme securityScheme = new OpenApiSecurityScheme() + { + Reference = new OpenApiReference() + { + Id = "jwt_auth", + Type = ReferenceType.SecurityScheme + } + }; + + OpenApiSecurityRequirement securityRequirements = new OpenApiSecurityRequirement() + { + {securityScheme, new string[] { }}, + }; + + options.AddSecurityRequirement(securityRequirements); +}); + +builder.Services.AddDbContext(option => +{ + option.UseSqlServer("UsersAccessConnection"); +}); +var app = builder.Build(); + +// Configure the HTTP request pipeline. +if (app.Environment.IsDevelopment()) +{ + app.UseSwagger(); + app.UseSwaggerUI(); + + using (var serviceScope = app.Services.CreateScope()) + { + var services = serviceScope.ServiceProvider; + var usersAccessProvider = services.GetRequiredService(); + usersAccessProvider.seedData(); + } +} + +app.UseAuthentication(); +app.UseAuthorization(); + +app.MapControllers(); +app.Run(); diff --git a/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Properties/launchSettings.json b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Properties/launchSettings.json new file mode 100644 index 0000000..859e680 --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Properties/launchSettings.json @@ -0,0 +1,31 @@ +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:28382", + "sslPort": 0 + } + }, + "profiles": { + "DamageAssesment.Api.Users": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "http://localhost:5027", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Providers/UserAccessProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Providers/UserAccessProvider.cs new file mode 100644 index 0000000..63a9772 --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Providers/UserAccessProvider.cs @@ -0,0 +1,305 @@ +using AutoMapper; +using DamageAssesment.Api.UsersAccess.Db; +using DamageAssesment.Api.UsersAccess.Interfaces; +using DamageAssesment.Api.UsersAccess.Models; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Options; +using Microsoft.IdentityModel.Tokens; +using System.Data; +using System.IdentityModel.Tokens.Jwt; +using System.Security.Claims; +using System.Text; + +namespace DamageAssesment.Api.UsersAccess.Providers +{ + public class UsersAccessProvider : IUsersAccessProvider + { + private readonly UsersAccessDbContext userAccessDbContext; + private readonly ILogger logger; + private readonly IMapper mapper; + //private readonly IEmployeeServiceProvider employeeServiceProvider; + private readonly JwtSettings jwtSettings; + private readonly ITokenServiceProvider tokenServiceProvider; + + public UsersAccessProvider(IOptions options, ITokenServiceProvider tokenServiceProvider, UsersAccessDbContext userAccessDbContext, IEmployeeServiceProvider employeeServiceProvider, ILogger logger, IMapper mapper) + { + this.userAccessDbContext = userAccessDbContext; + //this.employeeServiceProvider = employeeServiceProvider; + this.logger = logger; + this.mapper = mapper; + jwtSettings = options.Value; + this.tokenServiceProvider = tokenServiceProvider; + // seedData(); + } + + public void seedData() + { + if (!userAccessDbContext.Users.Any()) + { + userAccessDbContext.Users.Add(new Db.User { Id = 1, EmployeeId = 1, EmployeeCode = "Emp1", RoleId = 1, IsActive = true, CreateDate = DateTime.Now }); + userAccessDbContext.Users.Add(new Db.User { Id = 2, EmployeeId = 2, EmployeeCode = "Emp2", RoleId = 2, IsActive = true, CreateDate = DateTime.Now }); + userAccessDbContext.Users.Add(new Db.User { Id = 3, EmployeeId = 3, EmployeeCode = "Emp3", RoleId = 3, IsActive = true, CreateDate = DateTime.Now }); + userAccessDbContext.SaveChanges(); + } + + if (!userAccessDbContext.Roles.Any()) + { + userAccessDbContext.Roles.Add(new Db.Role { Id = 1, Name = "admin", Description ="Administrator role have full access" }); + userAccessDbContext.Roles.Add(new Db.Role { Id = 2, Name = "user", Description =" User role"}); + userAccessDbContext.Roles.Add(new Db.Role { Id = 3, Name = "survey", Description ="Survey role" }); + userAccessDbContext.Roles.Add(new Db.Role { Id = 4, Name = "report", Description ="Report role"}); + userAccessDbContext.Roles.Add(new Db.Role { Id = 5, Name = "document", Description ="Document role" }); + userAccessDbContext.SaveChanges(); + } + } + + public async Task<(bool IsSuccess, IEnumerable Users, string ErrorMessage)> GetUsersAsync() + { + try + { + logger?.LogInformation("Gell all Users from DB"); + var users = await userAccessDbContext.Users.ToListAsync(); + if (users != null) + { + logger?.LogInformation($"{users.Count} Items(s) found"); + var result = mapper.Map, IEnumerable>(users); + return (true, result, null); + } + return (false, null, "Not found"); + } + catch (Exception ex) + { + logger?.LogError(ex.ToString()); + return (false, null, ex.Message); + } + } + + public async Task<(bool IsSuccess, Models.User User, string ErrorMessage)> GetUsersAsync(int Id) + { + try + { + logger?.LogInformation("Querying Users table"); + var user = await userAccessDbContext.Users.SingleOrDefaultAsync(s => s.Id == Id); + if (user != null) + { + logger?.LogInformation($"User Id: {Id} found"); + var result = mapper.Map(user); + return (true, result, null); + } + return (false, null, "Not found"); + } + catch (Exception ex) + { + logger?.LogError(ex.ToString()); + return (false, null, ex.Message); + } + } + + public async Task<(bool IsSuccess, Models.User User, string ErrorMessage)> PostUserAsync(Models.User user) + { + try + { + if (user != null) + { + var _user = mapper.Map(user); + userAccessDbContext.Users.Add(_user); + user.Id = _user.Id; + await userAccessDbContext.SaveChangesAsync(); + return (true, user, "Successful"); + } + else + { + logger?.LogInformation($"null object cannot be added"); + return (false, null, $"null object cannot be added"); + } + } + catch (Exception ex) + { + logger?.LogError(ex.ToString()); + return (false, null, ex.Message); + } + } + + public async Task<(bool IsSuccess, Models.User User, string ErrorMessage)> PutUserAsync(int Id, Models.User user) + { + try + { + if (user != null) + { + var _user = await userAccessDbContext.Users.AsNoTracking().Where(s => s.Id == Id).SingleOrDefaultAsync(); + + if (_user != null) + { + int count = userAccessDbContext.Users.Where(u => u.Id != user.Id).Count(); + if (count == 0) + { + await userAccessDbContext.SaveChangesAsync(); + logger?.LogInformation($"Employee Id: {user.EmployeeId} updated successfuly"); + return (true, mapper.Map(_user), $"Employee Id: {_user.EmployeeId} updated successfuly"); + } + else + { + logger?.LogInformation($"Employee Id: {user.EmployeeId} is already exist"); + return (false, null, $"Employee Id: {user.EmployeeId} is already exist"); + } + } + else + { + logger?.LogInformation($"User Id : {Id} Not found"); + return (false, null, "Not Found"); + } + } + else + { + logger?.LogInformation($"User Id: {Id} Bad Request"); + return (false, null, "Bad request"); + } + } + catch (Exception ex) + { + logger?.LogError(ex.ToString()); + return (false, null, ex.Message); + } + } + + public async Task<(bool IsSuccess, Models.User User, string ErrorMessage)> DeleteUserAsync(int Id) + { + try + { + var user = await userAccessDbContext.Users.Where(x => x.Id == Id).SingleOrDefaultAsync(); + + if (user != null) + { + userAccessDbContext.Users.Remove(user); + await userAccessDbContext.SaveChangesAsync(); + logger?.LogInformation($"User Id: {Id} deleted Successfuly"); + return (true, mapper.Map(user), $"User Id: {Id} deleted Successfuly"); + } + else + { + logger?.LogInformation($"User Id : {Id} Not found"); + return (false, null, "Not Found"); + } + } + catch (Exception ex) + { + logger?.LogError(ex.ToString()); + return (false, null, ex.Message); + } + } + + public async Task<(bool IsSuccess, TokenResponse TokenResponse, string ErrorMessage)> AuthenticateAsync(string employecode) + { + + if (employecode != null) + { + //implementation for dadeschools authentication + // var employees = await employeeServiceProvider.getEmployeesAsync(); + // var employee = employees.Where(e=> e.EmployeeCode.ToLower() == employecode.ToLower()).SingleOrDefault(); + var user = userAccessDbContext.Users.Where(x => x.IsActive == true && x.EmployeeCode.ToLower() == employecode.ToLower()).SingleOrDefault(); + + if (user != null) + { + + var r = await GetRolesAsync(); + var role = r.Roles.Where(x => x.Id == user.RoleId).SingleOrDefault(); + + var authClaims = new List { + new Claim(ClaimTypes.Name, user.EmployeeCode), + new Claim(ClaimTypes.Role, role.Name), + new Claim(JwtRegisteredClaimNames.Jti,Guid.NewGuid().ToString()) + + }; + + /// Generate Token + var tokenhandler = new JwtSecurityTokenHandler(); + var tokenkey = Encoding.UTF8.GetBytes(jwtSettings.securitykey); + var tokendesc = new SecurityTokenDescriptor + { + Audience = "", + NotBefore = DateTime.Now, + Subject = new ClaimsIdentity(authClaims), + Expires = DateTime.Now.AddMinutes(30), + SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(tokenkey), SecurityAlgorithms.HmacSha256) + }; + var token = tokenhandler.CreateToken(tokendesc); + string finaltoken = tokenhandler.WriteToken(token); + + var response = new TokenResponse() { jwttoken = finaltoken, refreshtoken = await tokenServiceProvider.GenerateToken(mapper.Map(user)) }; + return (true, response, "Authentication success and token issued."); + } + else + { + return (false, null, "user inactive or not exist."); + } + } + + else + { + return (false, null, "Credentials are required to authenticate."); + } + } + public async Task<(bool IsSuccess, IEnumerable Roles, string ErrorMessage)> GetRolesAsync() + { + try + { + logger?.LogInformation("Gell all Roles from DB"); + var roles = await userAccessDbContext.Roles.ToListAsync(); + if (roles != null) + { + logger?.LogInformation($"{roles.Count} Items(s) found"); + var result = mapper.Map, IEnumerable>(roles); + return (true, result, null); + } + return (false, null, "Not found"); + } + catch (Exception ex) + { + logger?.LogError(ex.ToString()); + return (false, null, ex.Message); + } + } + + public async Task<(bool IsSuccess, Models.TokenResponse TokenResponse, string ErrorMessage)> RefreshTokenAsync(TokenResponse tokenResponse) + { + //Generate token + var tokenhandler = new JwtSecurityTokenHandler(); + var tokenkey = Encoding.UTF8.GetBytes(this.jwtSettings.securitykey); + SecurityToken securityToken; + var principal = tokenhandler.ValidateToken(tokenResponse.jwttoken, new TokenValidationParameters + { + ValidateIssuerSigningKey = true, + IssuerSigningKey = new SymmetricSecurityKey(tokenkey), + ValidateIssuer = false, + ValidateAudience = false, + + }, out securityToken); + + var token = securityToken as JwtSecurityToken; + if (token != null && !token.Header.Alg.Equals(SecurityAlgorithms.HmacSha256)) + { + return (false, null, "Unauthorized"); + } + var username = principal.Identity?.Name; + + var tokens = await userAccessDbContext.Tokens.ToListAsync(); + var users = await userAccessDbContext.Users.ToListAsync(); + + var user = (from u in users + join t in tokens + on u.Id equals t.UserId + where u.EmployeeId == 1 + && t.RefreshToken == tokenResponse.refreshtoken + select u).FirstOrDefault(); + + if (user == null) + return (false, null, "Invalid Token Response object provided"); + + var _user = mapper.Map(user); + var response = tokenServiceProvider.TokenAuthenticate(_user, principal.Claims.ToArray()).Result; + return (true, response, "Token authenticated and refreshed."); + } + + + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Services/EmployeeServiceProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Services/EmployeeServiceProvider.cs similarity index 90% rename from DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Services/EmployeeServiceProvider.cs rename to DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Services/EmployeeServiceProvider.cs index 8dd1352..a06c646 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Services/EmployeeServiceProvider.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Services/EmployeeServiceProvider.cs @@ -1,9 +1,8 @@ -using DamageAssesment.Api.SurveyResponses.Interfaces; -using DamageAssesment.Api.SurveyResponses.Models; -using Microsoft.AspNetCore.Mvc.Routing; +using DamageAssesment.Api.UsersAccess.Interfaces; +using DamageAssesment.Api.UsersAccess.Models; using Newtonsoft.Json; -namespace DamageAssesment.Api.SurveyResponses.Services +namespace DamageAssesment.Api.UsersAccess.Services { public class EmployeeServiceProvider : ServiceProviderBase, IEmployeeServiceProvider { diff --git a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Services/HttpUtil.cs b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Services/HttpUtil.cs similarity index 92% rename from DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Services/HttpUtil.cs rename to DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Services/HttpUtil.cs index 8b4755d..973278d 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Services/HttpUtil.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Services/HttpUtil.cs @@ -1,8 +1,8 @@ -using DamageAssesment.Api.SurveyResponses.Interfaces; +using DamageAssesment.Api.UsersAccess.Interfaces; using System.Net.Http.Headers; using System.Text; -namespace DamageAssesment.Api.SurveyResponses.Services +namespace DamageAssesment.Api.UsersAccess.Services { public class HttpUtil : IHttpUtil { @@ -27,7 +27,6 @@ namespace DamageAssesment.Api.SurveyResponses.Services { request.Content = new StringContent(JsonInput, Encoding.UTF8, "application/json"); } - var response = await httpClient.SendAsync(request, CancellationToken.None); response.EnsureSuccessStatusCode(); var responseString = await response.Content.ReadAsStringAsync(); diff --git a/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Services/ServiceProviderBase.cs b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Services/ServiceProviderBase.cs new file mode 100644 index 0000000..a90b839 --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Services/ServiceProviderBase.cs @@ -0,0 +1,25 @@ +using DamageAssesment.Api.UsersAccess.Interfaces; + +namespace DamageAssesment.Api.UsersAccess.Services +{ + public class ServiceProviderBase + { + protected readonly IConfiguration configuration; + protected readonly IHttpUtil httpUtil; + protected readonly ILogger logger; + protected string ressource; + protected string urlBase; + protected string url; + + + public ServiceProviderBase(IConfiguration configuration, IHttpUtil httpUtil, ILogger logger, string ressource, string urlBase) + { + this.configuration = configuration; + this.httpUtil = httpUtil; + this.logger = logger; + this.ressource = ressource; + this.urlBase = urlBase; + url = urlBase + ressource; + } + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Services/TokenServiceProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Services/TokenServiceProvider.cs new file mode 100644 index 0000000..91645b9 --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Services/TokenServiceProvider.cs @@ -0,0 +1,59 @@ +using System.IdentityModel.Tokens.Jwt; +using System.Security.Claims; +using System.Security.Cryptography; +using System.Text; +using DamageAssesment.Api.UsersAccess.Db; +using DamageAssesment.Api.UsersAccess.Interfaces; +using DamageAssesment.Api.UsersAccess.Models; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Options; +using Microsoft.IdentityModel.Tokens; + +namespace DamageAssesment.Api.UsersAccess.Services +{ + public class TokenServiceProvider : ITokenServiceProvider + { + private readonly UsersAccessDbContext usersAccessDbContext; + private readonly JwtSettings jwtSettings; + public TokenServiceProvider(IOptions options, UsersAccessDbContext usersAccessDbContext) + { + this.usersAccessDbContext = usersAccessDbContext; + this.jwtSettings = options.Value; + } + public async Task GenerateToken(Models.User user) + { + var randomnumber = new byte[32]; + using (var ramdomnumbergenerator = RandomNumberGenerator.Create()) + { + ramdomnumbergenerator.GetBytes(randomnumber); + string refreshtoken = Convert.ToBase64String(randomnumber); + var token = await usersAccessDbContext.Tokens.FirstOrDefaultAsync(item => item.UserId == user.Id); + if (token != null) + { + token.RefreshToken = refreshtoken; + } + else + { + usersAccessDbContext.Tokens.Add(new Db.Token() + { + UserId = user.Id, + RefreshToken = refreshtoken, + IsActive = true + }); + } + await usersAccessDbContext.SaveChangesAsync(); + + return refreshtoken; + } + } + + public async Task TokenAuthenticate(Models.User user, Claim[] claims) + { + var token = new JwtSecurityToken(claims: claims, expires: DateTime.Now.AddSeconds(20), + signingCredentials: new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings.securitykey)), SecurityAlgorithms.HmacSha256) + ); + var jwttoken = new JwtSecurityTokenHandler().WriteToken(token); + return new TokenResponse() { jwttoken = jwttoken, refreshtoken = await GenerateToken(user) }; + } + } +} \ No newline at end of file diff --git a/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/appsettings.Development.json b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/appsettings.Development.json new file mode 100644 index 0000000..0c208ae --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/appsettings.json b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/appsettings.json new file mode 100644 index 0000000..6437bdf --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/appsettings.json @@ -0,0 +1,40 @@ +{ + "JwtSettings": { + "securitykey": "bWlhbWkgZGFkZSBzY2hvb2xzIHNlY3JldCBrZXk=" + }, + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "EndPointSettings": { + "EmployeeUrlBase": "http://localhost:5135" + }, + "RessourceSettings": { + "Employee": "/Employees", + "EmployeeById": "/Employees/{0}" + }, + "AllowedHosts": "*", + "Dadeschools": { + "Authority": "https://dev-graph.dadeschools.net", + "TokenUrl": "https://dev-graph.dadeschools.net/connect/token", + "ClientId": "dmapi", + "ClientSecret": "bfce2c8d-2064-4a02-b19d-7f1d42b16eae", + "Name": "Dadeschools Identity Server" + }, + "Scopes": [ + { + "Name": "openid", + "Description": "Request an authentication token on your behalf" + }, + { + "Name": "profile", + "Description": "Read basic information about you such as your date of brith and full name" + } + ], + "ConnectionStrings": { + "UsersAccessConnection": "Server=tcp:da-dev.database.windows.net,1433;Initial Catalog=da-dev-db;Encrypt=True;User ID=admin-dev;Password=b3tgRABw8LGE75k;TrustServerCertificate=False;Connection Timeout=30;" + + } +} diff --git a/DamageAssesmentApi/DamageAssesment.SurveyResponses.Test/DamageAssesment.Api.Responses.Test.csproj b/DamageAssesmentApi/DamageAssesment.Responses.Test/DamageAssesment.Api.Responses.Test.csproj similarity index 90% rename from DamageAssesmentApi/DamageAssesment.SurveyResponses.Test/DamageAssesment.Api.Responses.Test.csproj rename to DamageAssesmentApi/DamageAssesment.Responses.Test/DamageAssesment.Api.Responses.Test.csproj index 03b9b5c..5190942 100644 --- a/DamageAssesmentApi/DamageAssesment.SurveyResponses.Test/DamageAssesment.Api.Responses.Test.csproj +++ b/DamageAssesmentApi/DamageAssesment.Responses.Test/DamageAssesment.Api.Responses.Test.csproj @@ -24,7 +24,7 @@ - + diff --git a/DamageAssesmentApi/DamageAssesment.SurveyResponses.Test/MockData.cs b/DamageAssesmentApi/DamageAssesment.Responses.Test/MockData.cs similarity index 88% rename from DamageAssesmentApi/DamageAssesment.SurveyResponses.Test/MockData.cs rename to DamageAssesmentApi/DamageAssesment.Responses.Test/MockData.cs index 5be421f..c7a52de 100644 --- a/DamageAssesmentApi/DamageAssesment.SurveyResponses.Test/MockData.cs +++ b/DamageAssesmentApi/DamageAssesment.Responses.Test/MockData.cs @@ -1,9 +1,9 @@  -using DamageAssesment.Api.SurveyResponses.Models; +using DamageAssesment.Api.Responses.Models; using System.Collections.Generic; using System.Text; -namespace DamageAssesment.Api.SurveyResponses.Test +namespace DamageAssesment.Api.Responses.Test { public class MockData { diff --git a/DamageAssesmentApi/DamageAssesment.SurveyResponses.Test/SurveyResponsesServiceTest.cs b/DamageAssesmentApi/DamageAssesment.Responses.Test/ResponsesServiceTest.cs similarity index 74% rename from DamageAssesmentApi/DamageAssesment.SurveyResponses.Test/SurveyResponsesServiceTest.cs rename to DamageAssesmentApi/DamageAssesment.Responses.Test/ResponsesServiceTest.cs index ffb8a4a..57e3630 100644 --- a/DamageAssesmentApi/DamageAssesment.SurveyResponses.Test/SurveyResponsesServiceTest.cs +++ b/DamageAssesmentApi/DamageAssesment.Responses.Test/ResponsesServiceTest.cs @@ -1,7 +1,7 @@ -using DamageAssesment.Api.SurveyResponses.Controllers; -using DamageAssesment.Api.SurveyResponses.Interfaces; -using DamageAssesment.Api.SurveyResponses.Models; -using DamageAssesment.Api.SurveyResponses.Test; +using DamageAssesment.Api.Responses.Controllers; +using DamageAssesment.Api.Responses.Interfaces; +using DamageAssesment.Api.Responses.Models; +using DamageAssesment.Api.Responses.Test; using Microsoft.AspNetCore.Mvc; using Moq; using Xunit; @@ -9,12 +9,14 @@ using Xunit; namespace DamageAssesment.SurveyResponses.Test { - public class SurveyResponsesServiceTest + public class ResponsesServiceTest { - Mock mockSurveyResponseService; - public SurveyResponsesServiceTest() + private Mock mockSurveyResponseService; + private string token { get; set; } + public ResponsesServiceTest() { mockSurveyResponseService = new Mock(); + token = Guid.NewGuid().ToString(); } [Fact(DisplayName = "Get SurveyResponses - Ok case")] @@ -22,9 +24,9 @@ namespace DamageAssesment.SurveyResponses.Test { SurveyResponse mockRequestObject = await MockData.getSurveyResponseObject(); var mockResponse = await MockData.getOkResponse(mockRequestObject); - mockSurveyResponseService.Setup(service => service.GetSurveyResponsesAsync(1)).ReturnsAsync(mockResponse); - var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object); - var result = (OkObjectResult)await surveyResponseProvider.GetSurveyResponsesAsync(1); + mockSurveyResponseService.Setup(service => service.GetSurveyResponsesAsync()).ReturnsAsync(mockResponse); + var surveyResponseProvider = new ResponsesController(mockSurveyResponseService.Object); + var result = (OkObjectResult)await surveyResponseProvider.GetSurveyResponsesAsync(); Assert.Equal(200, result.StatusCode); } @@ -32,9 +34,9 @@ namespace DamageAssesment.SurveyResponses.Test public async Task GetSurveyResponsesAsync_ShouldReturnStatusCode204() { var mockResponse = await MockData.getResponse(); - mockSurveyResponseService.Setup(service => service.GetSurveyResponsesAsync(1)).ReturnsAsync(mockResponse); - var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object); - var result = (BadRequestObjectResult)await surveyResponseProvider.GetSurveyResponsesAsync(1); + mockSurveyResponseService.Setup(service => service.GetSurveyResponsesAsync()).ReturnsAsync(mockResponse); + var surveyResponseProvider = new ResponsesController(mockSurveyResponseService.Object); + var result = (BadRequestObjectResult)await surveyResponseProvider.GetSurveyResponsesAsync(); Assert.Equal(400, result.StatusCode); } @@ -43,8 +45,8 @@ namespace DamageAssesment.SurveyResponses.Test { SurveyResponse mockRequestObject = await MockData.getSurveyResponseObject(); var mockResponse = await MockData.getOkResponse(); - mockSurveyResponseService.Setup(service => service.GetSurveyResponsesBySurveyAsync(1,1)).ReturnsAsync(mockResponse); - var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object); + mockSurveyResponseService.Setup(service => service.GetSurveyResponsesBySurveyAsync(1)).ReturnsAsync(mockResponse); + var surveyResponseProvider = new ResponsesController(mockSurveyResponseService.Object); var result = (OkObjectResult)await surveyResponseProvider.GetSurveyResponsesAsync(1); Assert.Equal(200, result.StatusCode); } @@ -53,8 +55,8 @@ namespace DamageAssesment.SurveyResponses.Test public async Task GetSurveyResponsesBySurveyAsync_ShouldReturnStatusCode204() { var mockResponse = await MockData.getResponse(); - mockSurveyResponseService.Setup(service => service.GetSurveyResponsesBySurveyAsync(1,1)).ReturnsAsync(mockResponse); - var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object); + mockSurveyResponseService.Setup(service => service.GetSurveyResponsesBySurveyAsync(1)).ReturnsAsync(mockResponse); + var surveyResponseProvider = new ResponsesController(mockSurveyResponseService.Object); var result = (NoContentResult)await surveyResponseProvider.GetSurveyResponsesAsync(1); Assert.Equal(204, result.StatusCode); } @@ -67,9 +69,9 @@ namespace DamageAssesment.SurveyResponses.Test { SurveyResponse mockRequestObject = await MockData.getSurveyResponseObject(); var mockResponse = await MockData.getOkResponse(); - mockSurveyResponseService.Setup(service => service.GetSurveyResponsesBySurveyAndLocationAsync(1, 1,1)).ReturnsAsync(mockResponse); - var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object); - var result = (OkObjectResult)await surveyResponseProvider.GetSurveyResponsesBySurveyAndLocationAsync(1, 1,1); + mockSurveyResponseService.Setup(service => service.GetSurveyResponsesBySurveyAndLocationAsync(1, 1)).ReturnsAsync(mockResponse); + var surveyResponseProvider = new ResponsesController(mockSurveyResponseService.Object); + var result = (OkObjectResult)await surveyResponseProvider.GetSurveyResponsesBySurveyAndLocationAsync(1, 1); Assert.Equal(200, result.StatusCode); } @@ -77,9 +79,9 @@ namespace DamageAssesment.SurveyResponses.Test public async Task GetSurveyResponsesBySurveyLocationAsync_ShouldReturnStatusCode204() { var mockResponse = await MockData.getResponse(); - mockSurveyResponseService.Setup(service => service.GetSurveyResponsesBySurveyAndLocationAsync(1, 1, 1)).ReturnsAsync(mockResponse); - var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object); - var result = (NoContentResult)await surveyResponseProvider.GetSurveyResponsesBySurveyAndLocationAsync(1, 1, 1); + mockSurveyResponseService.Setup(service => service.GetSurveyResponsesBySurveyAndLocationAsync(1, 1)).ReturnsAsync(mockResponse); + var surveyResponseProvider = new ResponsesController(mockSurveyResponseService.Object); + var result = (NoContentResult)await surveyResponseProvider.GetSurveyResponsesBySurveyAndLocationAsync(1, 1); Assert.Equal(204, result.StatusCode); } @@ -88,9 +90,9 @@ namespace DamageAssesment.SurveyResponses.Test { SurveyResponse mockRequestObject = await MockData.getSurveyResponseObject(); var mockResponse = await MockData.getOkResponse(); - mockSurveyResponseService.Setup(service => service.GetResponsesByAnswerAsync(1, 1, "Yes",1)).ReturnsAsync(mockResponse); - var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object); - var result = (OkObjectResult)await surveyResponseProvider.GetSurveyResponsesByAnswerAsyncAsync(1, 1, "Yes",1); + mockSurveyResponseService.Setup(service => service.GetResponsesByAnswerAsync(1, 1, "Yes")).ReturnsAsync(mockResponse); + var surveyResponseProvider = new ResponsesController(mockSurveyResponseService.Object); + var result = (OkObjectResult)await surveyResponseProvider.GetSurveyResponsesByAnswerAsyncAsync(1, 1, "Yes"); Assert.Equal(200, result.StatusCode); } @@ -98,9 +100,9 @@ namespace DamageAssesment.SurveyResponses.Test public async Task GetSurveyResponsesBySurveyQuestionAnswerAsync_ShouldReturnStatusCode204() { var mockResponse = await MockData.getResponse(); - mockSurveyResponseService.Setup(service => service.GetResponsesByAnswerAsync(1, 1, "Yes", 1)).ReturnsAsync(mockResponse); - var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object); - var result = (NoContentResult)await surveyResponseProvider.GetSurveyResponsesByAnswerAsyncAsync(1, 1, "Yes",1); + mockSurveyResponseService.Setup(service => service.GetResponsesByAnswerAsync(1, 1, "Yes")).ReturnsAsync(mockResponse); + var surveyResponseProvider = new ResponsesController(mockSurveyResponseService.Object); + var result = (NoContentResult)await surveyResponseProvider.GetSurveyResponsesByAnswerAsyncAsync(1, 1, "Yes"); Assert.Equal(204, result.StatusCode); } @@ -110,9 +112,9 @@ namespace DamageAssesment.SurveyResponses.Test { SurveyResponse mockRequestObject = await MockData.getSurveyResponseObject(); var mockResponse = await MockData.getOkResponse(); - mockSurveyResponseService.Setup(service => service.GetAnswersByRegionAsync(1,1)).ReturnsAsync(mockResponse); - var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object); - var result = (OkObjectResult)await surveyResponseProvider.GetAnswersByRegionAsync(1, 1); + mockSurveyResponseService.Setup(service => service.GetAnswersByRegionAsync(1)).ReturnsAsync(mockResponse); + var surveyResponseProvider = new ResponsesController(mockSurveyResponseService.Object); + var result = (OkObjectResult)await surveyResponseProvider.GetAnswersByRegionAsync(1); Assert.Equal(200, result.StatusCode); } @@ -120,9 +122,9 @@ namespace DamageAssesment.SurveyResponses.Test public async Task GetSurveyResponsesByRegionSurveyAsync_ShouldReturnStatusCode204() { var mockResponse = await MockData.getResponse(); - mockSurveyResponseService.Setup(service => service.GetAnswersByRegionAsync(1, 1)).ReturnsAsync(mockResponse); - var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object); - var result = (NoContentResult)await surveyResponseProvider.GetAnswersByRegionAsync(1, 1); + mockSurveyResponseService.Setup(service => service.GetAnswersByRegionAsync(1)).ReturnsAsync(mockResponse); + var surveyResponseProvider = new ResponsesController(mockSurveyResponseService.Object); + var result = (NoContentResult)await surveyResponseProvider.GetAnswersByRegionAsync(1); Assert.Equal(204, result.StatusCode); } @@ -131,9 +133,9 @@ namespace DamageAssesment.SurveyResponses.Test { SurveyResponse mockRequestObject = await MockData.getSurveyResponseObject(); var mockResponse = await MockData.getOkResponse(); - mockSurveyResponseService.Setup(service => service.GetSurveyResponsesByMaintenanceCenterAsync(1, 1)).ReturnsAsync(mockResponse); - var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object); - var result = (OkObjectResult)await surveyResponseProvider.GetAnswersByMaintenaceCentersync(1, 1); + mockSurveyResponseService.Setup(service => service.GetSurveyResponsesByMaintenanceCenterAsync(1)).ReturnsAsync(mockResponse); + var surveyResponseProvider = new ResponsesController(mockSurveyResponseService.Object); + var result = (OkObjectResult)await surveyResponseProvider.GetAnswersByMaintenaceCentersync(1); Assert.Equal(200, result.StatusCode); } @@ -141,9 +143,9 @@ namespace DamageAssesment.SurveyResponses.Test public async Task GetSurveyResponsesMaintenanceCenterSurveyAsync_ShouldReturnStatusCode204() { var mockResponse = await MockData.getResponse(); - mockSurveyResponseService.Setup(service => service.GetSurveyResponsesByMaintenanceCenterAsync(1, 1)).ReturnsAsync(mockResponse); - var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object); - var result = (NoContentResult)await surveyResponseProvider.GetAnswersByMaintenaceCentersync(1, 1); + mockSurveyResponseService.Setup(service => service.GetSurveyResponsesByMaintenanceCenterAsync(1)).ReturnsAsync(mockResponse); + var surveyResponseProvider = new ResponsesController(mockSurveyResponseService.Object); + var result = (NoContentResult)await surveyResponseProvider.GetAnswersByMaintenaceCentersync(1); Assert.Equal(204, result.StatusCode); } @@ -153,7 +155,7 @@ namespace DamageAssesment.SurveyResponses.Test SurveyResponse mockRequestObject = await MockData.getSurveyResponseObject(); var mockResponse = await MockData.getOkResponse(); mockSurveyResponseService.Setup(service => service.GetSurveyResponseByIdAsync(1)).ReturnsAsync(mockResponse); - var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object); + var surveyResponseProvider = new ResponsesController(mockSurveyResponseService.Object); var result = (OkObjectResult)await surveyResponseProvider.GetSurveyResponseByIdAsync(1); Assert.Equal(200, result.StatusCode); } @@ -163,7 +165,7 @@ namespace DamageAssesment.SurveyResponses.Test { var mockResponse = await MockData.getResponse(); mockSurveyResponseService.Setup(service => service.GetSurveyResponseByIdAsync(1)).ReturnsAsync(mockResponse); - var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object); + var surveyResponseProvider = new ResponsesController(mockSurveyResponseService.Object); var result = (NoContentResult)await surveyResponseProvider.GetSurveyResponseByIdAsync(1); Assert.Equal(204, result.StatusCode); } @@ -175,7 +177,7 @@ namespace DamageAssesment.SurveyResponses.Test SurveyResponse mockRequestObject = await MockData.getSurveyResponseObject(); var mockResponse = await MockData.getOkResponse(mockRequestObject); mockSurveyResponseService.Setup(service => service.PostSurveyResponseAsync(mockRequestObject)).ReturnsAsync(mockResponse); - var surveyResponseController = new SurveyResponsesController(mockSurveyResponseService.Object); + var surveyResponseController = new ResponsesController(mockSurveyResponseService.Object); var result = (OkObjectResult)await surveyResponseController.PostSurveysAsync(mockRequestObject); Assert.Equal(200, result.StatusCode); } @@ -186,7 +188,7 @@ namespace DamageAssesment.SurveyResponses.Test SurveyResponse mockRequestObject = await MockData.getSurveyResponseObject(); var mockResponse = await MockData.getResponse(); mockSurveyResponseService.Setup(service => service.PostSurveyResponseAsync(mockRequestObject)).ReturnsAsync(mockResponse); - var surveyResponseController = new SurveyResponsesController(mockSurveyResponseService.Object); + var surveyResponseController = new ResponsesController(mockSurveyResponseService.Object); var result = (BadRequestObjectResult)await surveyResponseController.PostSurveysAsync(mockRequestObject); Assert.Equal(400, result.StatusCode); } @@ -197,7 +199,7 @@ namespace DamageAssesment.SurveyResponses.Test SurveyResponse mockRequestObject = await MockData.getSurveyResponseObject(); var mockResponse = await MockData.getOkResponse(mockRequestObject); mockSurveyResponseService.Setup(service => service.PutSurveyResponseAsync(1, mockRequestObject)).ReturnsAsync(mockResponse); - var surveyResponseController = new SurveyResponsesController(mockSurveyResponseService.Object); + var surveyResponseController = new ResponsesController(mockSurveyResponseService.Object); var result = (OkObjectResult)await surveyResponseController.PutSurveyResponseAsync(1, mockRequestObject); Assert.Equal(200, result.StatusCode); } @@ -208,7 +210,7 @@ namespace DamageAssesment.SurveyResponses.Test SurveyResponse mockRequestObject = await MockData.getSurveyResponseObject(); var mockResponse = await MockData.getResponse(); mockSurveyResponseService.Setup(service => service.PutSurveyResponseAsync(1, mockRequestObject)).ReturnsAsync(mockResponse); ; - var surveyResponseController = new SurveyResponsesController(mockSurveyResponseService.Object); + var surveyResponseController = new ResponsesController(mockSurveyResponseService.Object); var result = (BadRequestObjectResult)await surveyResponseController.PutSurveyResponseAsync(1, mockRequestObject); Assert.Equal(400, result.StatusCode); } @@ -219,7 +221,7 @@ namespace DamageAssesment.SurveyResponses.Test SurveyResponse mockRequestObject = await MockData.getSurveyResponseObject(); var mockResponse = await MockData.getOkResponse(mockRequestObject); mockSurveyResponseService.Setup(service => service.DeleteSurveyResponseAsync(1)).ReturnsAsync(mockResponse); - var surveyResponseController = new SurveyResponsesController(mockSurveyResponseService.Object); + var surveyResponseController = new ResponsesController(mockSurveyResponseService.Object); var result = (OkObjectResult)await surveyResponseController.DeleteSurveyResponseAsync(1); Assert.Equal(200, result.StatusCode); } @@ -229,7 +231,7 @@ namespace DamageAssesment.SurveyResponses.Test { var mockResponse = await MockData.getResponse(); mockSurveyResponseService.Setup(service => service.DeleteSurveyResponseAsync(1)).ReturnsAsync(mockResponse); ; - var surveyResponseController = new SurveyResponsesController(mockSurveyResponseService.Object); + var surveyResponseController = new ResponsesController(mockSurveyResponseService.Object); var result = (NotFoundResult)await surveyResponseController.DeleteSurveyResponseAsync(1); Assert.Equal(404, result.StatusCode); } diff --git a/DamageAssesmentApi/DamageAssesment.sln b/DamageAssesmentApi/DamageAssesment.sln index b92b664..60e123e 100644 --- a/DamageAssesmentApi/DamageAssesment.sln +++ b/DamageAssesmentApi/DamageAssesment.sln @@ -17,13 +17,13 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DamageAssesment.Api.Locations", "DamageAssesment.Api.Locations\DamageAssesment.Api.Locations.csproj", "{746C67BF-9949-4361-B5D2-358C7607750E}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DamageAssesment.Api.Responses", "DamageAssesment.Api.SurveyResponses\DamageAssesment.Api.Responses.csproj", "{D11808FE-AD1C-4BA6-87FD-9D18B2DC81F2}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DamageAssesment.Api.Responses", "DamageAssesment.Api.Responses\DamageAssesment.Api.Responses.csproj", "{D11808FE-AD1C-4BA6-87FD-9D18B2DC81F2}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DamageAssesment.Api.Questions.Test", "DamageAssesment.Api.QuestionsTest\DamageAssesment.Api.Questions.Test.csproj", "{35CD9231-034D-4999-BCFC-1786DD007ED2}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DamageAssesment.Api.Surveys.Test", "DamageAssesment.Api.Surveys.Test\DamageAssesment.Api.Surveys.Test.csproj", "{ADFB79E3-83C9-454F-A070-49D167BD28CC}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DamageAssesment.Api.Responses.Test", "DamageAssesment.SurveyResponses.Test\DamageAssesment.Api.Responses.Test.csproj", "{6F4B9C9D-CE5D-421A-876F-57D0FEDF8049}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DamageAssesment.Api.Responses.Test", "DamageAssesment.Responses.Test\DamageAssesment.Api.Responses.Test.csproj", "{6F4B9C9D-CE5D-421A-876F-57D0FEDF8049}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DamageAssesment.Api.Attachments.Test", "DamageAssesment.Api.Attachments.Test\DamageAssesment.Api.Attachments.Test.csproj", "{730E5718-FCE1-42C0-AB76-EA020896A788}" EndProject @@ -41,6 +41,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DamageAssesment.Api.DocuLin EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DamageAssesment.Api.DocuLinks.Test", "DamageAssesment.Api.DocuLinks.Test\DamageAssesment.Api.DocuLinks.Test.csproj", "{A7F17ED7-71D2-4FD0-87E5-D83415078FC0}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DamageAssesment.Api.UsersAccess", "DamageAssesment.Api.UsersAccess\DamageAssesment.Api.UsersAccess.csproj", "{40240AD6-90D2-4128-BCDF-12C77D1B1B55}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DamageAssesment.Api.UsersAccess.Test", "DamageAssesment.Api.UsersAccess.Test\DamageAssesment.Api.UsersAccess.Test.csproj", "{ADAF9385-262C-4A37-A603-A53B77EA515D}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -111,6 +115,14 @@ Global {A7F17ED7-71D2-4FD0-87E5-D83415078FC0}.Debug|Any CPU.Build.0 = Debug|Any CPU {A7F17ED7-71D2-4FD0-87E5-D83415078FC0}.Release|Any CPU.ActiveCfg = Release|Any CPU {A7F17ED7-71D2-4FD0-87E5-D83415078FC0}.Release|Any CPU.Build.0 = Release|Any CPU + {40240AD6-90D2-4128-BCDF-12C77D1B1B55}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {40240AD6-90D2-4128-BCDF-12C77D1B1B55}.Debug|Any CPU.Build.0 = Debug|Any CPU + {40240AD6-90D2-4128-BCDF-12C77D1B1B55}.Release|Any CPU.ActiveCfg = Release|Any CPU + {40240AD6-90D2-4128-BCDF-12C77D1B1B55}.Release|Any CPU.Build.0 = Release|Any CPU + {ADAF9385-262C-4A37-A603-A53B77EA515D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {ADAF9385-262C-4A37-A603-A53B77EA515D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {ADAF9385-262C-4A37-A603-A53B77EA515D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {ADAF9385-262C-4A37-A603-A53B77EA515D}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE