Compare commits

...

14 Commits

Author SHA1 Message Date
Santhosh S
f650ee562b merge with docker-branch 2023-09-05 00:44:41 -04:00
Santhosh S
a8105ab0f2 Merge with dev branch 2023-09-05 00:15:17 -04:00
Santhosh S
4d6ae0f0f8 Seed data commented for Attachments and SurveyResponse 2023-09-04 22:04:58 -04:00
Santhosh S
cc4b58d072 Code cleanup variable names 2023-09-04 15:50:26 -04:00
Santhosh S
a52f6e0cf9 Fix for Data seed issue,Url Correction for SurveyResponses 2023-09-04 15:40:10 -04:00
Santhosh S
af004ce565 Survey Renamed to Surveys 2023-09-04 01:23:53 -04:00
Santhosh S
f5ae6a2f3f Meged swagger changes from server version 2023-09-03 18:56:01 -04:00
Santhosh S
220f18da8d Merge branch 'dev' into docker-branch 2023-09-03 18:47:12 -04:00
Sysadmin
b558fdf651 dev server swagger updation 2023-09-03 17:55:03 -04:00
Santhosh S
9ec45aa9ff Attachments_1.txt 2023-09-01 14:13:52 -04:00
Santhosh S
e5eb414876 Updated API route 2023-08-31 11:10:38 -04:00
Santhosh S
a130aff300 Dockerise Sprint 2 Code with bug fix 2023-08-31 11:10:38 -04:00
Santhosh S
e0cb2ccc7d Updated API route 2023-08-29 22:23:40 -04:00
Santhosh S
82cfa5706a Dockerise Sprint 2 Code with bug fix 2023-08-28 01:03:24 -04:00
80 changed files with 1736 additions and 159 deletions

5
.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
################################################################################
# This .gitignore file was automatically created by Microsoft(R) Visual Studio.
################################################################################
/DamageAssesmentApi/nginx.conf

View File

@ -0,0 +1,25 @@
**/.classpath
**/.dockerignore
**/.env
**/.git
**/.gitignore
**/.project
**/.settings
**/.toolstarget
**/.vs
**/.vscode
**/*.*proj.user
**/*.dbmdl
**/*.jfm
**/azds.yaml
**/bin
**/charts
**/docker-compose*
**/Dockerfile*
**/node_modules
**/npm-debug.log
**/obj
**/secrets.dev.yaml
**/values.dev.yaml
LICENSE
README.md

View File

@ -5,7 +5,7 @@ using Microsoft.OpenApi.Any;
namespace DamageAssesment.Api.Answers.Controllers
{
[Route("api")]
//[Route("api")]
[ApiController]
public class AnswersController: ControllerBase
{

View File

@ -1,10 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<DockerComposeProjectPath>..\docker-compose.dcproj</DockerComposeProjectPath>
</PropertyGroup>
<ItemGroup>
@ -12,6 +14,7 @@
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.21" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.9" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.18.1" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
</ItemGroup>

View File

@ -0,0 +1,39 @@
#See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.
# Use the ASP.NET base image
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
# Use the SDK image for building
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
# Copy the project file and restore dependencies
COPY ["DamageAssesment.Api.Answers/DamageAssesment.Api.Answers.csproj", "DamageAssesment.Api.Answers/"]
RUN dotnet restore "DamageAssesment.Api.Answers/DamageAssesment.Api.Answers.csproj"
# Copy the source code
COPY . .
WORKDIR "/src/DamageAssesment.Api.Answers"
# Build the application
RUN dotnet build "DamageAssesment.Api.Answers.csproj" -c Release -o /app/build
# Publish the application
FROM build AS publish
RUN dotnet publish "DamageAssesment.Api.Answers.csproj" -c Release -o /app/publish /p:UseAppHost=false
# Set up the final image
FROM base AS final
WORKDIR /app
# Copy the published files
COPY --from=publish /app/publish .
## Set up the volume and copy the XML comments
#VOLUME /xmlcomments
#COPY ["DamageAssesment.Api.Answers.xml", "/xmlcomments/DamageAssesment.Api.Answers.xml"]
#
# Specify the entry point for the container
ENTRYPOINT ["dotnet", "DamageAssesment.Api.Answers.dll"]

View File

@ -2,6 +2,8 @@ using DamageAssesment.Api.Answers.Db;
using DamageAssesment.Api.Answers.Interfaces;
using DamageAssesment.Api.Answers.Providers;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
using Microsoft.OpenApi.Models;
using System.Reflection;
var builder = WebApplication.CreateBuilder(args);
@ -14,10 +16,13 @@ builder.Services.AddEndpointsApiExplorer();
//builder.Services.AddSwaggerGen();
builder.Services.AddSwaggerGen(c =>
{
// Include XML comments from your assembly
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
c.IncludeXmlComments(xmlPath);
});
builder.Services.AddScoped<IAnswersProvider, AnswersProvider>();
builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies()); //4/30
@ -32,8 +37,21 @@ var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
//using (var serviceScope = app.Services.CreateScope())
//{
// var services = serviceScope.ServiceProvider;
// var answerProvider = services.GetRequiredService<IAnswersProvider>();
// answerProvider.SeedData();
//}
app.UseSwagger();
app.UseSwaggerUI();
app.UseSwaggerUI(
options =>
{
//switch for local environment
//options.SwaggerEndpoint("/swagger/v1/swagger.json", "");
options.SwaggerEndpoint("/answers/swagger/v1/swagger.json","" );
} );
}
app.UseAuthorization();

View File

@ -7,7 +7,7 @@ using System.Net.Http.Headers;
namespace DamageAssesment.Api.Attachments.Controllers
{
[Route("api")]
//[Route("api")]
[ApiController]
public class AttachmentsController : ControllerBase
{

View File

@ -5,6 +5,8 @@
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<DockerComposeProjectPath>..\docker-compose.dcproj</DockerComposeProjectPath>
</PropertyGroup>
<ItemGroup>
@ -14,6 +16,7 @@
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="2.2.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.5" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.18.1" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
</ItemGroup>

View File

@ -0,0 +1,47 @@
#See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.
# Use the ASP.NET base image
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
# Use the SDK image for building
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
# Copy the project file and restore dependencies
COPY ["DamageAssesment.Api.Attachments/DamageAssesment.Api.Attachments.csproj", "DamageAssesment.Api.Attachments/"]
RUN dotnet restore "DamageAssesment.Api.Attachments/DamageAssesment.Api.Attachments.csproj"
# Copy the source code
COPY . .
WORKDIR "/src/DamageAssesment.Api.Attachments"
# Build the application
RUN dotnet build "DamageAssesment.Api.Attachments.csproj" -c Release -o /app/build
# Publish the application
FROM build AS publish
RUN dotnet publish "DamageAssesment.Api.Attachments.csproj" -c Release -o /app/publish /p:UseAppHost=false
# Set up the final image
FROM base AS final
WORKDIR /app
# Copy the published files
COPY --from=publish /app/publish .
# Create directories for attachments and set permissions
RUN mkdir -p /app/DMS_Attachments/Active && \
mkdir -p /app/DMS_Attachments/Deleted && \
chown -R www-data:www-data /app/DMS_Attachments
# Update appsettings.json with the correct paths for attachments
RUN sed -i 's#"folderpath": "DMS_Attachments/Active"#"folderpath": "/app/DMS_Attachments/Active"#' appsettings.json && \
sed -i 's#"Deletepath": "DMS_Attachments/Deleted"#"Deletepath": "/app/DMS_Attachments/Deleted"#' appsettings.json
## Set up the volume and copy the XML comments
#VOLUME /xmlcomments
#COPY ["DamageAssesment.Api.Attachments/bin/Release/net6.0/DamageAssesment.Api.Attachments.xml", "/xmlcomments/"]
#
# Specify the entry point for the container
ENTRYPOINT ["dotnet", "DamageAssesment.Api.Attachments.dll"]

View File

@ -13,5 +13,6 @@ namespace DamageAssesment.Api.Attachments.Interfaces
Task<(bool IsSuccess, int counter, string Path)> DeleteBulkAttachmentsAsync(int responseId, List<int> answerIds);
Task<(bool IsSuccess, int counter, string message)> GetAttachmentCounter();
Task<(bool IsSuccess, IEnumerable<Models.Attachment> Attachments, string ErrorMessage)> GetAttachmentInfo(List<AnswerInfo> answers);
}
}

View File

@ -42,7 +42,14 @@ var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
app.UseSwaggerUI(options => {
//switch for local environment
// options.SwaggerEndpoint("/swagger/v1/swagger.json", "");
options.SwaggerEndpoint("/attachments/swagger/v1/swagger.json", "");
});
}
app.UseAuthorization();

View File

@ -4,7 +4,7 @@ using Microsoft.AspNetCore.Mvc;
namespace DamageAssesment.Api.Employees.Controllers
{
[Route("api")]
//[Route("api")]
[ApiController]
public class EmployeesController : ControllerBase
{

View File

@ -5,6 +5,8 @@
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<DockerComposeProjectPath>..\docker-compose.dcproj</DockerComposeProjectPath>
</PropertyGroup>
<ItemGroup>
@ -12,6 +14,7 @@
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.21" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.5" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.18.1" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
</ItemGroup>

View File

@ -0,0 +1,39 @@
#See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.
# Use the ASP.NET base image
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
# Use the SDK image for building
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
# Copy the project file and restore dependencies
COPY ["DamageAssesment.Api.Employees/DamageAssesment.Api.Employees.csproj", "DamageAssesment.Api.Employees/"]
RUN dotnet restore "DamageAssesment.Api.Employees/DamageAssesment.Api.Employees.csproj"
# Copy the source code
COPY . .
WORKDIR "/src/DamageAssesment.Api.Employees"
# Build the application
RUN dotnet build "DamageAssesment.Api.Employees.csproj" -c Release -o /app/build
# Publish the application
FROM build AS publish
RUN dotnet publish "DamageAssesment.Api.Employees.csproj" -c Release -o /app/publish /p:UseAppHost=false
# Set up the final image
FROM base AS final
WORKDIR /app
# Copy the published files
COPY --from=publish /app/publish .
## Set up the volume and copy the XML comments
#VOLUME /xmlcomments
#COPY ["DamageAssesment.Api.Employees.xml", "/xmlcomments/DamageAssesment.Api.Employees.xml"]
# Specify the entry point for the container
ENTRYPOINT ["dotnet", "DamageAssesment.Api.Employees.dll"]

View File

@ -32,15 +32,21 @@ 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 employeesProvider = services.GetRequiredService<IEmployeesProvider>();
employeesProvider.SeedData();
var employeeProvider = services.GetRequiredService<IEmployeesProvider>();
employeeProvider.SeedData();
}
app.UseSwagger();
app.UseSwaggerUI(options =>
{
//switch for local environment
// options.SwaggerEndpoint("/swagger/v1/swagger.json", "");
options.SwaggerEndpoint("/employees/swagger/v1/swagger.json", "");
});
}
app.UseAuthorization();

View File

@ -1,23 +1,14 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:14425",
"sslPort": 0
}
},
{
"profiles": {
"DamageAssesment.Api.Employees": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "http://localhost:5135",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"dotnetRunMessages": true,
"applicationUrl": "http://localhost:5135"
},
"IIS Express": {
"commandName": "IISExpress",
@ -26,6 +17,21 @@
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"Docker": {
"commandName": "Docker",
"launchBrowser": true,
"launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger",
"publishAllPorts": true
}
},
"$schema": "https://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:14425",
"sslPort": 0
}
}
}

View File

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>

View File

@ -4,7 +4,8 @@ using Microsoft.AspNetCore.Mvc;
namespace DamageAssesment.Api.Locations.Controllers
{
[Route("api")]
[Route("Locations")]
//[Route("[controller]")]
[ApiController]
public class LocationsController : ControllerBase
{
@ -18,7 +19,8 @@ namespace DamageAssesment.Api.Locations.Controllers
/// Get all locations.
/// </summary>
[HttpGet("Locations")]
//[HttpGet("locations")]
[HttpGet]
public async Task<ActionResult> GetLocationsAsync()
{
@ -27,14 +29,14 @@ namespace DamageAssesment.Api.Locations.Controllers
{
return Ok(result.locations);
}
return NoContent();
return NotFound();
}
/// <summary>
/// Get all locations based on locationdId.
/// </summary>
[HttpGet("Locations/{id}")]
[HttpGet("{id}")]
public async Task<ActionResult> GetLocationByIdAsync(string id)
{
@ -50,12 +52,12 @@ namespace DamageAssesment.Api.Locations.Controllers
/// Update a Location.
/// </summary>
[HttpPut("Locations")]
public async Task<IActionResult> UpdateLocation(Models.Location Location)
[HttpPut("{locations}")]
public async Task<IActionResult> UpdateLocation(Models.Location location)
{
if (Location != null)
if (location != null)
{
var result = await this.LocationProvider.UpdateLocationAsync(Location);
var result = await this.LocationProvider.UpdateLocationAsync(location);
if (result.IsSuccess)
{
return Ok(result.ErrorMessage);
@ -68,7 +70,7 @@ namespace DamageAssesment.Api.Locations.Controllers
/// Save a new location.
/// </summary>
[HttpPost("Locations")]
[HttpPost("{locations}")]
public async Task<IActionResult> CreateLocation(Models.Location Location)
{
if (Location != null)
@ -78,15 +80,15 @@ namespace DamageAssesment.Api.Locations.Controllers
{
return Ok(result.Question);
}
return BadRequest();
return NotFound();
}
return BadRequest();
return CreatedAtRoute("DefaultApi", new { id = Location.Id }, Location);
}
/// <summary>
/// Delete an existing location.
/// </summary>
[HttpDelete("Locations/{id}")]
[HttpDelete("{id}")]
public async Task<IActionResult> DeleteLocation(string id)
{
var result = await this.LocationProvider.DeleteLocationAsync(id);

View File

@ -3,7 +3,8 @@ using Microsoft.AspNetCore.Mvc;
namespace DamageAssesment.Api.Locations.Controllers
{
[Route("api/[controller]")]
//[Route("api/[controller]")]
[Route("[controller]")]
[ApiController]
public class RegionsController : ControllerBase
{
@ -45,7 +46,7 @@ namespace DamageAssesment.Api.Locations.Controllers
/// POST request for creating a new region.
/// </summary>
[HttpPost]
[HttpPost("{region}")]
public async Task<ActionResult> PostRegionAsync(Models.Region region)
{
var result = await this.regionProvider.PostRegionAsync(region);
@ -59,7 +60,7 @@ namespace DamageAssesment.Api.Locations.Controllers
/// PUT request for updating an existing region.
/// </summary>
[HttpPut]
[HttpPut("{region}")]
public async Task<ActionResult> PutRegionAsync(Models.Region region)
{
var result = await this.regionProvider.PutRegionAsync(region);

View File

@ -5,6 +5,8 @@
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<DockerComposeProjectPath>..\docker-compose.dcproj</DockerComposeProjectPath>
</PropertyGroup>
<ItemGroup>
@ -12,6 +14,7 @@
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.21" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.5" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.18.1" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
</ItemGroup>

View File

@ -0,0 +1,39 @@
#See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.
# Use the ASP.NET base image
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
# Use the SDK image for building
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
# Copy the project file and restore dependencies
COPY ["DamageAssesment.Api.Locations/DamageAssesment.Api.Locations.csproj", "DamageAssesment.Api.Locations/"]
RUN dotnet restore "DamageAssesment.Api.Locations/DamageAssesment.Api.Locations.csproj"
# Copy the source code
COPY . .
WORKDIR "/src/DamageAssesment.Api.Locations"
# Build the application
RUN dotnet build "DamageAssesment.Api.Locations.csproj" -c Release -o /app/build
# Publish the application
FROM build AS publish
RUN dotnet publish "DamageAssesment.Api.Locations.csproj" -c Release -o /app/publish /p:UseAppHost=false
# Set up the final image
FROM base AS final
WORKDIR /app
# Copy the published files
COPY --from=publish /app/publish .
## Set up the volume and copy the XML comments
#VOLUME /xmlcomments
#COPY ["DamageAssesment.Api.Locations.xml", "/xmlcomments/DamageAssesment.Api.Locations.xml"]
# Specify the entry point for the container
ENTRYPOINT ["dotnet", "DamageAssesment.Api.Locations.dll"]

View File

@ -31,9 +31,6 @@ 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;
@ -42,6 +39,17 @@ if (app.Environment.IsDevelopment())
locationProvider.SeedData();
regionProvider.SeedData();
}
app.UseSwagger();
app.UseSwaggerUI(options =>
{
//switch for local environment
// options.SwaggerEndpoint("/swagger/v1/swagger.json","");
options.SwaggerEndpoint("locations/swagger/v1/swagger.json", "");
});
}
app.UseAuthorization();

View File

@ -1,23 +1,14 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:20458",
"sslPort": 0
}
},
{
"profiles": {
"DamageAssesment.Api.Locations": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "http://localhost:5213",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"dotnetRunMessages": true,
"applicationUrl": "http://localhost:5213"
},
"IIS Express": {
"commandName": "IISExpress",
@ -26,6 +17,21 @@
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"Docker": {
"commandName": "Docker",
"launchBrowser": true,
"launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger",
"publishAllPorts": true
}
},
"$schema": "https://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:20458",
"sslPort": 0
}
}
}

View File

@ -3,7 +3,7 @@ using Microsoft.AspNetCore.Mvc;
namespace DamageAssesment.Api.Questions.Controllers
{
[Route("api")]
//[Route("api")]
[ApiController]
public class QuestionsController : ControllerBase
{
@ -17,7 +17,7 @@ namespace DamageAssesment.Api.Questions.Controllers
}
/// <summary>
/// GET request for retrieving questions.
/// GET request for retrieving questions, e.g api/fr/Questions (default returns all language).
/// </summary>
// get all questions

View File

@ -5,6 +5,8 @@
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<DockerComposeProjectPath>..\docker-compose.dcproj</DockerComposeProjectPath>
</PropertyGroup>
<ItemGroup>
@ -12,6 +14,7 @@
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.21" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.5" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.18.1" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
</ItemGroup>

View File

@ -0,0 +1,38 @@
#See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.
# Use the ASP.NET base image
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
# Use the SDK image for building
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
# Copy the project file and restore dependencies
COPY ["DamageAssesment.Api.Questions/DamageAssesment.Api.Questions.csproj", "DamageAssesment.Api.Questions/"]
RUN dotnet restore "DamageAssesment.Api.Questions/DamageAssesment.Api.Questions.csproj"
# Copy the source code
COPY . .
WORKDIR "/src/DamageAssesment.Api.Questions"
# Build the application
RUN dotnet build "DamageAssesment.Api.Questions.csproj" -c Release -o /app/build
# Publish the application
FROM build AS publish
RUN dotnet publish "DamageAssesment.Api.Questions.csproj" -c Release -o /app/publish /p:UseAppHost=false
# Set up the final image
FROM base AS final
WORKDIR /app
# Copy the published files
COPY --from=publish /app/publish .
## Set up the volume and copy the XML comments
#VOLUME /xmlcomments
#COPY ["DamageAssesment.Api.Questions.xml", "/xmlcomments/DamageAssesment.Api.Questions.xml"]
# Specify the entry point for the container
ENTRYPOINT ["dotnet", "DamageAssesment.Api.Questions.dll"]

View File

@ -4,5 +4,6 @@
{
Task<(bool IsSuccess, Db.QuestionType QuestionType, string ErrorMessage)> GetQuestionTypeAsync(int Id);
Task<(bool IsSuccess, IEnumerable<Db.QuestionType> QuestionTypes, string ErrorMessage)> GetQuestionTypesAsync();
}
}

View File

@ -35,15 +35,20 @@ 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 questionProvider = services.GetRequiredService<IQuestionsProvider>();
questionProvider.SeedData();
}
app.UseSwagger();
app.UseSwaggerUI(options => {
//switch for local environment
// options.SwaggerEndpoint("/swagger/v1/swagger.json", "");
options.SwaggerEndpoint("/questions/swagger/v1/swagger.json", "");
});
}
app.UseAuthorization();

View File

@ -1,23 +1,14 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:60754",
"sslPort": 0
}
},
{
"profiles": {
"DamageAssesment.Api.Questions": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "http://localhost:5133",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"dotnetRunMessages": true,
"applicationUrl": "http://localhost:5133"
},
"IIS Express": {
"commandName": "IISExpress",
@ -26,6 +17,21 @@
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"Docker": {
"commandName": "Docker",
"launchBrowser": true,
"launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger",
"publishAllPorts": true
}
},
"$schema": "https://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:60754",
"sslPort": 0
}
}
}

View File

@ -21,7 +21,7 @@ namespace DamageAssesment.Api.Questions.Providers
this.questionDbContext = questionDbContext;
this.logger = logger;
this.mapper = mapper;
SeedData();
// SeedData();
}
public void SeedData()

View File

@ -6,7 +6,7 @@ using Microsoft.Extensions.Configuration;
namespace DamageAssesment.Api.SurveyResponses.Controllers
{
[Route("api")]
[Route("Responses")]
[ApiController]
public class SurveyResponsesController : ControllerBase
{
@ -20,7 +20,7 @@ namespace DamageAssesment.Api.SurveyResponses.Controllers
/// GET request for retrieving survey responses.
/// </summary>
[HttpGet("SurveyResponses")]
[HttpGet]
public async Task<ActionResult> GetSurveyResponsesAsync()
{
var result = await this.surveyResponseProvider.GetSurveyResponsesAsync();
@ -38,7 +38,7 @@ namespace DamageAssesment.Api.SurveyResponses.Controllers
/// GET request for retrieving survey responses by survey ID.
/// </summary>
[HttpGet("SurveyResponses/{surveyId}")]
[HttpGet("surveys/{surveyId}")]
public async Task<ActionResult> GetSurveyResponsesAsync(int surveyId)
{
var result = await this.surveyResponseProvider.GetSurveyResponsesBySurveyAsync(surveyId);
@ -54,7 +54,7 @@ namespace DamageAssesment.Api.SurveyResponses.Controllers
/// <param name="surveyId">The ID of the survey for which responses are to be retrieved.</param>
/// <param name="locationId">The ID of the location for which responses are to be retrieved.</param>
[HttpGet("Responses/{surveyId}/{locationId}")]
[HttpGet("{surveyId}/{locationId}")]
public async Task<ActionResult> GetSurveyResponsesBySurveyAndLocationAsync(int surveyId, string locationId)
{
var result = await this.surveyResponseProvider.GetSurveyResponsesBySurveyAndLocationAsync(surveyId, locationId);
@ -72,7 +72,7 @@ namespace DamageAssesment.Api.SurveyResponses.Controllers
/// <param name="questionId">The ID of the question for which responses are to be retrieved.</param>
/// <param name="answer">The answer for which responses are to be retrieved.</param>
[HttpGet("ResponsesByAnswer/{surveyId}/{questionId}/{answer}")]
[HttpGet("ByAnswers/{surveyId}/{questionId}/{answer}")]
public async Task<ActionResult> GetSurveyResponsesByAnswerAsyncAsync(int surveyId, int questionId, string answer)
{
var result = await surveyResponseProvider.GetResponsesByAnswerAsync(surveyId, questionId, answer);
@ -88,7 +88,7 @@ namespace DamageAssesment.Api.SurveyResponses.Controllers
/// </summary>
/// <param name="surveyId">The ID of the survey for which answers are to be retrieved.</param>
[HttpGet("AnswersByRegion/{surveyId}")]
[HttpGet("ByRegion/{surveyId}")]
public async Task<ActionResult> GetAnswersByRegionAsync(int surveyId)
{
var result = await this.surveyResponseProvider.GetAnswersByRegionAsync(surveyId);
@ -103,7 +103,7 @@ namespace DamageAssesment.Api.SurveyResponses.Controllers
/// </summary>
/// <param name="surveyId">The ID of the survey for which responses are to be retrieved.</param>
[HttpGet("AnswersByMaintenanceCenter/{surveyId}")]
[HttpGet("ByMaintenanceCenter/{surveyId}")]
public async Task<ActionResult> GetAnswersByMaintenaceCentersync(int surveyId)
{
var result = await this.surveyResponseProvider.GetSurveyResponsesByMaintenanceCenterAsync(surveyId);
@ -134,7 +134,7 @@ namespace DamageAssesment.Api.SurveyResponses.Controllers
/// </summary>
/// <param name="surveyResponse">The survey response object to be created.</param>
[HttpPost("SurveyResponses")]
[HttpPost]
public async Task<ActionResult> PostSurveysAsync(Models.SurveyResponse surveyResponse)
{
var result = await this.surveyResponseProvider.PostSurveyResponseAsync(surveyResponse);
@ -150,7 +150,7 @@ namespace DamageAssesment.Api.SurveyResponses.Controllers
/// <param name="Id">The ID of the survey response to be updated.</param>
/// <param name="surveyResponse">The updated survey response object.</param>
[HttpPut("SurveyResponses/{Id}")]
[HttpPut("{Id}")]
public async Task<ActionResult> PutSurveyResponseAsync(int Id, Models.SurveyResponse surveyResponse)
{
var result = await this.surveyResponseProvider.PutSurveyResponseAsync(Id, surveyResponse);
@ -167,7 +167,7 @@ namespace DamageAssesment.Api.SurveyResponses.Controllers
/// DELETE request for deleting an existing survey response.
/// </summary>
[HttpDelete("SurveyResponses/{Id}")]
[HttpDelete("{Id}")]
public async Task<ActionResult> DeleteSurveyResponseAsync(int Id)
{
var result = await this.surveyResponseProvider.DeleteSurveyResponseAsync(Id);
@ -182,7 +182,7 @@ namespace DamageAssesment.Api.SurveyResponses.Controllers
/// </summary>
/// <param name="request">The answers to be submitted for the survey.</param>
[HttpPost("SurveyResponses/Answers")]
[HttpPost("Answers")]
public async Task<ActionResult> PostSurveyAnswersAsync(Request request)
{
var result = await this.surveyResponseProvider.PostSurveyAnswersAsync(request);

View File

@ -5,6 +5,8 @@
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<DockerComposeProjectPath>..\docker-compose.dcproj</DockerComposeProjectPath>
</PropertyGroup>
<ItemGroup>
@ -13,6 +15,7 @@
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.5" />
<PackageReference Include="Microsoft.Extensions.Http.Polly" Version="7.0.5" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.18.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
</ItemGroup>

View File

@ -0,0 +1,41 @@
#See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.
# Use the ASP.NET base image
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
# Use the SDK image for building
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
# Copy the project file and restore dependencies
COPY ["DamageAssesment.Api.SurveyResponses/DamageAssesment.Api.SurveyResponses.csproj", "DamageAssesment.Api.SurveyResponses/"]
RUN dotnet restore "DamageAssesment.Api.SurveyResponses/DamageAssesment.Api.SurveyResponses.csproj"
# Copy the source code
COPY . .
# Change the working directory to the project directory
WORKDIR "/src/DamageAssesment.Api.SurveyResponses"
# Build the application
RUN dotnet build "DamageAssesment.Api.SurveyResponses.csproj" -c Release -o /app/build
# Publish the application
FROM build AS publish
RUN dotnet publish "DamageAssesment.Api.SurveyResponses.csproj" -c Release -o /app/publish /p:UseAppHost=false
# Set up the final image
FROM base AS final
WORKDIR /app
# Copy the published files from the publish stage
COPY --from=publish /app/publish .
## Set up the volume and copy the XML comments
#VOLUME /xmlcomments
#COPY ["DamageAssesment.Api.SurveyResponses.xml", "/xmlcomments/DamageAssesment.Api.SurveyResponses.xml"]
#
# Specify the entry point for the container
ENTRYPOINT ["dotnet", "DamageAssesment.Api.SurveyResponses.dll"]

View File

@ -0,0 +1,10 @@
namespace DamageAssesment.Api.SurveyResponses.Models
{
public class QuestionRequest
{
public int QuestionId { get; set; }
public string AnswerText { get; set; }
public string Comment { get; set; }
public List<FileModel> PostedFiles { get; set; } = new List<FileModel>();
}
}

View File

@ -52,7 +52,12 @@ var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
app.UseSwaggerUI(options => {
//switch for local environment
// options.SwaggerEndpoint("/swagger/v1/swagger.json", "");
options.SwaggerEndpoint("/surveyresponses/swagger/v1/swagger.json", "");
});
}
app.UseAuthorization();

View File

@ -1,23 +1,14 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:58856",
"sslPort": 0
}
},
{
"profiles": {
"DamageAssesment.Api.SurveyResponses": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "http://localhost:5104",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"dotnetRunMessages": true,
"applicationUrl": "http://localhost:5104"
},
"IIS Express": {
"commandName": "IISExpress",
@ -26,6 +17,21 @@
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"Docker": {
"commandName": "Docker",
"launchBrowser": true,
"launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger",
"publishAllPorts": true
}
},
"$schema": "https://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:58856",
"sslPort": 0
}
}
}

View File

@ -31,6 +31,7 @@ namespace DamageAssesment.Api.SurveyResponses.Providers
this.questionServiceProvider = questionServiceProvider;
this.surveyServiceProvider = surveyServiceProvider;
this.mapper = mapper;
//seedData();
}

View File

@ -6,14 +6,13 @@
}
},
"AllowedHosts": "*",
"EndPointSettings": {
"AnswerUrlBase": "http://localhost:5200",
"LocationUrlBase": "http://localhost:5213",
"RegionUrlBase": "http://localhost:5211",
"QuestionUrlBase": "http://localhost:5133",
"EmployeeUrlBase": "http://localhost:5135",
"AttachmentUrlBase": "http://localhost:5243",
"SurveyUrlBase": "http://localhost:5009"
"EndPointSettings": {
"AnswerUrlBase": "http://damageassesment.api.answers:80",
"LocationUrlBase": "http://damageassesment.api.locations:80",
"QuestionUrlBase": "http://damageassesment.api.questions:80",
"EmployeeUrlBase": "http://damageassesment.api.employees:80",
"AttachmentUrlBase": "http://damageassesment.api.attachments:80",
"SurveyUrlBase": "http://damageassesment.api.survey:80"
}
}

View File

@ -24,7 +24,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DamageAssesment.Api.Surveys\DamageAssesment.Api.Survey.csproj" />
<ProjectReference Include="..\DamageAssesment.Api.Surveys\DamageAssesment.Api.Surveys.csproj" />
</ItemGroup>
</Project>

View File

@ -3,7 +3,7 @@ using Microsoft.AspNetCore.Mvc;
namespace DamageAssesment.Api.Surveys.Controllers
{
[Route("api")]
//[Route("api")]
[ApiController]
public class SurveysController : ControllerBase
{
@ -13,16 +13,19 @@ namespace DamageAssesment.Api.Surveys.Controllers
{
this.surveyProvider = surveyProvider;
}
/// <summary>
/// GET request for retrieving surveys.
/// </summary>
/// <summary>
/// GET request for retrieving surveys
/// </summary>
/// <remarks>
/// This endpoint retrieves surveys. You can use it to get all surveys or surveys for a specific language(optional).
/// </remarks>
[Route("Surveys")]
[Route("{Language}/Surveys")]
[Route("{language}/Surveys")]
[HttpGet]
public async Task<ActionResult> GetSurveysAsync(string? Language)
public async Task<ActionResult> GetSurveysAsync(string? language)
{
var result = await this.surveyProvider.GetSurveysAsync(Language);
var result = await this.surveyProvider.GetSurveysAsync(language);
if (result.IsSuccess)
{
return Ok(result.Surveys);
@ -34,11 +37,11 @@ namespace DamageAssesment.Api.Surveys.Controllers
/// GET request for retrieving surveys by ID.
/// </summary>
[Route("Surveys/{Id}")]
[Route("{Language}/Surveys/{Id}")]
[Route("{language}/Surveys/{Id}")]
[HttpGet]
public async Task<ActionResult> GetSurveysAsync(int Id, string? Language)
public async Task<ActionResult> GetSurveysAsync(int Id, string? language)
{
var result = await this.surveyProvider.GetSurveysAsync(Id, Language);
var result = await this.surveyProvider.GetSurveysAsync(Id, language);
if (result.IsSuccess)
{
return Ok(result.Surveys);

View File

@ -5,6 +5,8 @@
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<DockerComposeProjectPath>..\docker-compose.dcproj</DockerComposeProjectPath>
</PropertyGroup>
<ItemGroup>
@ -12,6 +14,7 @@
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.21" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.5" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.18.1" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
</ItemGroup>

View File

@ -0,0 +1,25 @@
##See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.
# Use the ASP.NET runtime image as the base image
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
# Use the .NET SDK image for the build stage
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["DamageAssesment.Api.Surveys/DamageAssesment.Api.Survey.csproj", "DamageAssesment.Api.Surveys/"]
RUN dotnet restore "DamageAssesment.Api.Surveys/DamageAssesment.Api.Survey.csproj"
COPY . .
WORKDIR "/src/DamageAssesment.Api.Surveys"
RUN dotnet build "DamageAssesment.Api.Survey.csproj" -c Release -o /app/build
# Publish the application
FROM build AS publish
RUN dotnet publish "DamageAssesment.Api.Survey.csproj" -c Release -o /app/publish /p:UseAppHost=false
# Use the ASP.NET runtime image again for the final stage
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "DamageAssesment.Api.Survey.dll"]

View File

@ -6,6 +6,7 @@ using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using System.Text;
using System.Reflection;
using Microsoft.AspNetCore.Builder;
var builder = WebApplication.CreateBuilder(args);
@ -52,6 +53,12 @@ var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI(options => {
//switch for local environment
// options.SwaggerEndpoint("/swagger/v1/swagger.json", "");
options.SwaggerEndpoint("/surveys/swagger/v1/swagger.json", "");
});
app.UseSwaggerUI();
using (var serviceScope = app.Services.CreateScope())

View File

@ -1,23 +1,14 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:51498",
"sslPort": 0
}
},
{
"profiles": {
"DamageAssesment.Api.Surveys": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "http://localhost:5009",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"dotnetRunMessages": true,
"applicationUrl": "http://localhost:5009"
},
"IIS Express": {
"commandName": "IISExpress",
@ -26,6 +17,21 @@
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"Docker": {
"commandName": "Docker",
"launchBrowser": true,
"launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger",
"publishAllPorts": true
}
},
"$schema": "https://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:51498",
"sslPort": 0
}
}
}

View File

@ -54,7 +54,7 @@ namespace DamageAssesment.Api.Surveys.Providers
IEnumerable<Models.Survey> surveysList = null;
try
{
logger?.LogInformation("Gell all Surveys from DB");
logger?.LogInformation("Get all Surveys from DB");
var surveys = await surveyDbContext.Surveys.Where(s => s.IsEnabled == true).ToListAsync();
var surveyTranslations = await surveyDbContext.SurveysTranslation.ToListAsync();

View File

@ -0,0 +1,21 @@
namespace DamageAssesment.Api.UsersAccess.Bases
{
public class ServiceProviderBase
{
protected readonly IConfiguration configuration;
protected readonly HttpClient httpClient;
protected private readonly ILogger<ServiceProviderBase> logger;
protected string ressource;
protected string urlBase;
public ServiceProviderBase(IConfiguration configuration, HttpClient httpClient, ILogger<ServiceProviderBase> logger, string ressource, string urlBase)
{
this.configuration = configuration;
this.httpClient = httpClient;
this.logger = logger;
this.ressource = ressource;
this.urlBase = urlBase;
}
}
}

View File

@ -0,0 +1,97 @@
using DamageAssesment.Api.UsersAccess.Interfaces;
using DamageAssesment.Api.UsersAccess.Models;
using Microsoft.AspNetCore.Mvc;
namespace DamageAssesment.Api.UsersAccess.Controllers
{
[Route("api")]
[ApiController]
public class UsersAccessController : ControllerBase
{
private IUsersAccessProvider userAccessProvider;
public UsersAccessController(IUsersAccessProvider userAccessProvider)
{
this.userAccessProvider = userAccessProvider;
}
[HttpPost("authenticate")]
public async Task<ActionResult> AuthenticateAsync(UserCredentials userCredentials)
{
var result = await userAccessProvider.AuthenticateAsync(userCredentials);
if (result.IsSuccess)
{
return Ok(result.TokenResponse);
}
return Unauthorized(result.ErrorMessage);
}
[HttpPost("refreshToken")]
public async Task<ActionResult> RefreshTokenAsync(TokenResponse tokenResponse)
{
var result = await userAccessProvider.RefreshTokenAsync(tokenResponse);
if (result.IsSuccess)
{
return Ok(result.TokenResponse);
}
return Unauthorized(result.ErrorMessage);
}
[HttpGet("users")]
public async Task<ActionResult> GetUsersAsync()
{
var result = await userAccessProvider.GetUsersAsync();
if (result.IsSuccess)
{
return Ok(result.Users);
}
return NoContent();
}
[HttpGet("users/{Id}")]
public async Task<ActionResult> GetUsersAsync(int Id)
{
var result = await userAccessProvider.GetUsersAsync(Id);
if (result.IsSuccess)
{
return Ok(result.User);
}
return NotFound();
}
[HttpPost("users")]
public async Task<ActionResult> PostUserAsync(User user)
{
var result = await userAccessProvider.PostUserAsync(user);
if (result.IsSuccess)
{
return Ok(result.User);
}
return BadRequest(result.ErrorMessage);
}
[HttpPut("users/{Id}")]
public async Task<ActionResult> 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);
}
[HttpDelete("users/{Id}")]
public async Task<ActionResult> DeleteSurveysAsync(int Id)
{
var result = await userAccessProvider.DeleteUserAsync(Id);
if (result.IsSuccess)
{
return Ok(result.User);
}
return NotFound();
}
}
}

View File

@ -0,0 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<<<<<<<< HEAD:DamageAssesmentApi/DamageAssesment.Api.UsersAccess/DamageAssesment.Api.UsersAccess.csproj
========
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<DockerComposeProjectPath>..\docker-compose.dcproj</DockerComposeProjectPath>
>>>>>>>> origin/server-branch:DamageAssesmentApi/DamageAssesment.Api.Surveys/DamageAssesment.Api.Survey.csproj
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.1" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.21" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.5" />
<<<<<<<< HEAD:DamageAssesmentApi/DamageAssesment.Api.UsersAccess/DamageAssesment.Api.UsersAccess.csproj
<PackageReference Include="Microsoft.Extensions.Http.Polly" Version="7.0.10" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
========
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.18.1" />
>>>>>>>> origin/server-branch:DamageAssesmentApi/DamageAssesment.Api.Surveys/DamageAssesment.Api.Survey.csproj
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
</ItemGroup>
</Project>

View File

@ -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; }
}
}

View File

@ -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 string Id { get; set; }
[Required]
[ForeignKey("User")]
public int UserId { get; set; }
public string? RefreshToken { get; set; }
public bool? IsActive { get; set; }
}
}

View File

@ -0,0 +1,27 @@
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 string EmployeeId { 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; }
}
}

View File

@ -0,0 +1,17 @@
using Microsoft.EntityFrameworkCore;
namespace DamageAssesment.Api.UsersAccess.Db
{
public class UsersAccessDbContext:DbContext
{
public DbSet<Db.User> Users { get; set; }
public DbSet<Db.Role> Roles { get; set; }
public DbSet<Db.Token> Tokens { get; set; }
public UsersAccessDbContext(DbContextOptions options) : base(options)
{
}
}
}

View File

@ -0,0 +1,10 @@
using DamageAssesment.Api.UsersAccess.Models;
namespace DamageAssesment.Api.UsersAccess.Interfaces
{
public interface IEmployeeServiceProvider
{
Task<List<Employee>> getEmployeesAsync();
Task<Employee> getEmployeeAsync(string employeeID);
}
}

View File

@ -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);
}
}

View File

@ -0,0 +1,11 @@
using DamageAssesment.Api.UsersAccess.Models;
using System.Security.Claims;
namespace DamageAssesment.Api.UsersAccess.Interfaces
{
public interface ITokenServiceProvider
{
Task<string> GenerateToken(User user);
Task<TokenResponse> TokenAuthenticate(User user, Claim[] claims);
}
}

View File

@ -0,0 +1,16 @@
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<Models.Role> Roles, string ErrorMessage)> GetRolesAsync();
public Task<(bool IsSuccess, Models.TokenResponse TokenResponse, string ErrorMessage)> AuthenticateAsync(UserCredentials userCredentials);
public Task<(bool IsSuccess, Models.TokenResponse TokenResponse, string ErrorMessage)>RefreshTokenAsync(TokenResponse tokenResponse);
}
}

View File

@ -0,0 +1,21 @@
using System.ComponentModel.DataAnnotations;
namespace DamageAssesment.Api.UsersAccess.Models
{
public class Employee
{
public string Id { get; set; }
[StringLength(50)]
public string Name { get; set; }
public DateTime BirthDate { get; set; }
[StringLength(50)]
public string OfficePhoneNumber { get; set; }
[StringLength(50)]
public string Email { get; set; }
public bool IsActive { get; set; }
}
}

View File

@ -0,0 +1,9 @@
using System.ComponentModel.DataAnnotations;
namespace DamageAssesment.Api.UsersAccess.Models
{
public class JwtSettings
{
public string securitykey { get; set; }
}
}

View File

@ -0,0 +1,9 @@
using System.ComponentModel.DataAnnotations;
namespace DamageAssesment.Api.UsersAccess.Models
{
public class Role {
public int Id { get; set; }
public string Name { get; set; }
public string? Description { get; set; }
}
}

View File

@ -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; }
}
}

View File

@ -0,0 +1,8 @@
namespace DamageAssesment.Api.UsersAccess.Models
{
public class TokenResponse
{
public string? jwttoken { get; set; }
public string? refreshtoken { get; set; }
}
}

View File

@ -0,0 +1,12 @@
namespace DamageAssesment.Api.UsersAccess.Models
{
public class User
{
public int Id { get; set; }
public string EmployeeId { get; set; }
public int RoleId { get; set; }
public bool? IsActive { get; set; }
public DateTime? CreateDate { get; set; }
public DateTime? UpdateDate { get; set; }
}
}

View File

@ -0,0 +1,5 @@
public class UserCredentials
{
public string? username { get; set; }
// public string? password { get; set; }
}

View File

@ -0,0 +1,14 @@
namespace DamageAssesment.Api.UsersAccess.Profiles
{
public class UsersAccessProfile : AutoMapper.Profile
{
public UsersAccessProfile()
{
CreateMap<Db.User, Models.User>();
CreateMap<Models.User, Db.User>();
CreateMap<Db.Role, Models.Role>();
CreateMap<Models.Role, Db.Role>();
}
}
}

View File

@ -0,0 +1,77 @@
using DamageAssesment.Api.UsersAccess.Db;
using DamageAssesment.Api.UsersAccess.Interfaces;
using DamageAssesment.Api.UsersAccess.Providers;
using DamageAssesment.Api.UsersAccess.Models;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using System.Text;
using Polly;
using DamageAssesment.Api.SurveyResponses.Providers;
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<string>("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
};
});
var _jwtsettings = builder.Configuration.GetSection("JwtSettings");
builder.Services.Configure<JwtSettings>(_jwtsettings);
builder.Services.AddHttpClient<IEmployeeServiceProvider, EmployeeServiceProvider>().
AddTransientHttpErrorPolicy(policy => policy.WaitAndRetryAsync(maxApiCallRetries, _ => TimeSpan.FromSeconds(intervalToRetry))).
AddTransientHttpErrorPolicy(policy => policy.CircuitBreakerAsync(maxRetryForCircuitBraker, TimeSpan.FromSeconds(intervalForCircuitBraker)));
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddScoped<IUsersAccessProvider, UsersAccessProvider>();
builder.Services.AddScoped<ITokenServiceProvider, TokenServiceProvider>();
builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddDbContext<UsersAccessDbContext>(option =>
{
option.UseInMemoryDatabase("UsersAccess");
});
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();

View File

@ -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"
}
}
}
}

View File

@ -0,0 +1,58 @@
using DamageAssesment.Api.UsersAccess.Bases;
using DamageAssesment.Api.UsersAccess.Interfaces;
using DamageAssesment.Api.UsersAccess.Models;
using Newtonsoft.Json;
using System.Reflection;
namespace DamageAssesment.Api.SurveyResponses.Providers
{
public class EmployeeServiceProvider :ServiceProviderBase, IEmployeeServiceProvider
{
public EmployeeServiceProvider(IConfiguration configuration, HttpClient httpClient, ILogger<EmployeeServiceProvider> logger) : base(configuration, httpClient, logger, "/api/Employees", configuration.GetValue<string>("EndPointSettings:EmployeeUrlBase"))
{
}
public async Task<List<Employee>> getEmployeesAsync()
{
try
{
httpClient.BaseAddress = new Uri(urlBase);
var response = await httpClient.GetAsync(ressource);
response.EnsureSuccessStatusCode();
var responseString = await response.Content.ReadAsStringAsync();
var employees = JsonConvert.DeserializeObject<List<Employee>>(responseString);
if (employees == null || !employees.Any())
return null;
else return employees;
}
catch (Exception ex)
{
logger?.LogError($"Exception Found : {ex.Message} - Ref: EmployeeServiceProvider.getEmployeesAsync()");
return null;
}
}
public async Task<Employee> getEmployeeAsync(string employeeID)
{
try
{
httpClient.BaseAddress = new Uri(urlBase);
//ressource = ressource + "/" + employeeID;
var response = await httpClient.GetAsync("/api/Employees/"+ employeeID);
response.EnsureSuccessStatusCode();
var responseString = await response.Content.ReadAsStringAsync();
var employee = JsonConvert.DeserializeObject<Employee>(responseString);
if (employee == null )
return null;
else return employee;
}
catch (Exception ex)
{
logger?.LogError($"Exception Found : {ex.Message} - Ref: EmployeeServiceProvider.getEmployeeAsync()");
return null;
}
}
}
}

View File

@ -0,0 +1,57 @@
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;
public class TokenServiceProvider : ITokenServiceProvider
{
private readonly UsersAccessDbContext usersAccessDbContext;
private readonly JwtSettings jwtSettings;
public TokenServiceProvider(IOptions<JwtSettings> options,UsersAccessDbContext usersAccessDbContext)
{
this.usersAccessDbContext = usersAccessDbContext;
this.jwtSettings = options.Value;
}
public async Task<string> GenerateToken(DamageAssesment.Api.UsersAccess.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 DamageAssesment.Api.UsersAccess.Db.Token()
{
Id = new Random().Next().ToString(),
UserId = user.Id,
RefreshToken = refreshtoken,
IsActive = true
});
}
await usersAccessDbContext.SaveChangesAsync();
return refreshtoken;
}
}
public async Task<TokenResponse> TokenAuthenticate(DamageAssesment.Api.UsersAccess.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) };
}
}

View File

@ -0,0 +1,341 @@
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<UsersAccessProvider> logger;
private readonly IMapper mapper;
private readonly IEmployeeServiceProvider employeeServiceProvider;
private readonly JwtSettings jwtSettings;
private readonly ITokenServiceProvider tokenServiceProvider;
public UsersAccessProvider(IOptions<JwtSettings> options, ITokenServiceProvider tokenServiceProvider, UsersAccessDbContext userAccessDbContext, IEmployeeServiceProvider employeeServiceProvider, ILogger<UsersAccessProvider> logger, IMapper mapper)
{
this.userAccessDbContext = userAccessDbContext;
this.employeeServiceProvider = employeeServiceProvider;
this.logger = logger;
this.mapper = mapper;
jwtSettings = options.Value;
this.tokenServiceProvider = tokenServiceProvider;
seedData();
}
private void seedData()
{
if (!userAccessDbContext.Users.Any())
{
userAccessDbContext.Users.Add(new Db.User { Id = 1, EmployeeId = "Emp1", RoleId = 1 });
userAccessDbContext.Users.Add(new Db.User { Id = 2, EmployeeId = "Emp2", RoleId = 2 });
userAccessDbContext.Users.Add(new Db.User { Id = 3, EmployeeId = "Emp3", RoleId = 3 });
userAccessDbContext.SaveChanges();
}
if (!userAccessDbContext.Roles.Any())
{
userAccessDbContext.Roles.Add(new Db.Role { Id = 1, Name = "admin" });
userAccessDbContext.Roles.Add(new Db.Role { Id = 2, Name = "user" });
userAccessDbContext.Roles.Add(new Db.Role { Id = 3, Name = "survey" });
userAccessDbContext.Roles.Add(new Db.Role { Id = 4, Name = "report" });
userAccessDbContext.Roles.Add(new Db.Role { Id = 5, Name = "document" });
userAccessDbContext.SaveChanges();
}
}
public async Task<(bool IsSuccess, IEnumerable<Models.User> 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<Db.User>, IEnumerable<Models.User>>(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<Db.User, Models.User>(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 users = await userAccessDbContext.Users.ToListAsync();
int count = users.Where(u => u.EmployeeId == user.EmployeeId).Count();
if (count == 0)
{
user.Id = users.Count + 1;
userAccessDbContext.Users.Add(mapper.Map<Models.User, Db.User>(user));
await userAccessDbContext.SaveChangesAsync();
return (true, user, "Successful");
}
else
{
logger?.LogInformation($"Employee Id: {user.EmployeeId} is already exist");
return (false, null, $"Employee Id: {user.EmployeeId} is already exist");
}
}
else
{
logger?.LogInformation($"Employee Id: {user.EmployeeId} cannot be added");
return (false, null, $"Employee Id: {user.EmployeeId} 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.Where(s => s.Id == Id).SingleOrDefaultAsync();
if (_user != null)
{
int count = userAccessDbContext.Users.Where(u => u.Id != user.Id && u.EmployeeId == user.EmployeeId).Count();
if (count == 0)
{
_user.EmployeeId = user.EmployeeId;
_user.RoleId = user.RoleId;
_user.IsActive = user.IsActive;
_user.UpdateDate = DateTime.Now;
await userAccessDbContext.SaveChangesAsync();
logger?.LogInformation($"Employee Id: {user.EmployeeId} updated successfuly");
return (true, mapper.Map<Db.User, Models.User>(_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<Db.User, Models.User>(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(UserCredentials userCredentials)
{
if (userCredentials != null)
{
//implementation for dadeschools authentication
var employee = await employeeServiceProvider.getEmployeeAsync(userCredentials.username);
if (employee != null)
{
var result = await GetUsersAsync();
if (result.IsSuccess)
{
var user = result.Users.Where(x => x.IsActive == true && x.EmployeeId.ToLower().Equals(userCredentials.username.ToLower())).SingleOrDefault();
if (user != null)
{
var r = await GetRolesAsync();
var role = r.Roles.Where(x => x.Id == user.RoleId).SingleOrDefault();
var authClaims = new List<Claim> {
new Claim(ClaimTypes.Name, user.EmployeeId),
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(user) };
return (true, response, "Authentication success and token issued.");
}
else
{
return (false, null, "user inactive or not exist.");
}
}
else
{
return (false, null, "users list empty.");
}
}
else
{
return (false, null, "Employee not exist.");
}
}
else
{
return (false, null, "Credentials are required to authenticate.");
}
}
public async Task<(bool IsSuccess, IEnumerable<Models.Role> 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<Db.Role>, IEnumerable<Models.Role>>(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 == username
&& t.RefreshToken == tokenResponse.refreshtoken
select u).FirstOrDefault();
if (user == null)
return (false, null, "Invalid Token Response object provided");
var _user = mapper.Map<Db.User, Models.User>(user);
var response = tokenServiceProvider.TokenAuthenticate(_user, principal.Claims.ToArray()).Result;
return (true, response, "Token authenticated and refreshed.");
}
}
}

View File

@ -0,0 +1,15 @@
{
"JwtSettings": {
"securitykey": "bWlhbWkgZGFkZSBzY2hvb2xzIHNlY3JldCBrZXk="
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"EndPointSettings": {
"EmployeeUrlBase": "http://localhost:5135"
},
"AllowedHosts": "*"
}

View File

@ -9,19 +9,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DamageAssesment.Api.Answers
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DamageAssesment.Api.Attachments", "DamageAssesment.Api.Attachments\DamageAssesment.Api.Attachments.csproj", "{FF619F3A-D1BB-4934-A0E1-6EF7D0DAACD6}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{4CB40DC2-D9D2-4384-A7A6-9968F5C777A2}"
ProjectSection(SolutionItems) = preProject
ReadMe.txt = ReadMe.txt
ReadMe4Dev.txt = ReadMe4Dev.txt
EndProjectSection
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.SurveyResponses", "DamageAssesment.Api.SurveyResponses\DamageAssesment.Api.SurveyResponses.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.Survey.Test", "DamageAssesment.Api.Surveys.Test\DamageAssesment.Api.Survey.Test.csproj", "{ADFB79E3-83C9-454F-A070-49D167BD28CC}"
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.SurveyResponses.Test", "DamageAssesment.SurveyResponses.Test\DamageAssesment.Api.SurveyResponses.Test.csproj", "{6F4B9C9D-CE5D-421A-876F-57D0FEDF8049}"
EndProject
@ -29,7 +23,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DamageAssesment.Api.Attachm
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DamageAssesment.Api.Locations.Test", "DamageAssesment.Api.Locations.Test\DamageAssesment.Api.Locations.Test.csproj", "{DA68AE47-6825-41ED-9107-5151822FB083}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DamageAssesment.Api.Survey", "DamageAssesment.Api.Surveys\DamageAssesment.Api.Survey.csproj", "{55481AED-6801-47DB-A176-A6FA92002081}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DamageAssesment.Api.Surveys", "DamageAssesment.Api.Surveys\DamageAssesment.Api.Surveys.csproj", "{55481AED-6801-47DB-A176-A6FA92002081}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DamageAssesment.Api.Answers.Test", "DamageAssesment.Api.Answers.Test\DamageAssesment.Api.Answers.Test.csproj", "{594A47AC-DF50-47E5-903D-A856CADDF573}"
EndProject
@ -37,9 +31,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DamageAssesment.Api.Employe
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DamageAssesment.Api.Employees.Test", "DamageAssesment.Api.Employees.Test\DamageAssesment.Api.Employees.Test.csproj", "{D6BF9AE9-72FA-4726-A326-35A35D27FFB8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DamageAssesment.Api.Documents", "DamageAssesment.Api.Documents\DamageAssesment.Api.Documents.csproj", "{977C1053-9D63-4153-B61B-C3D2F1010F9F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DamageAssesment.Api.Documents.Test", "DamageAssesment.Api.Documents.Test\DamageAssesment.Api.Documents.Test.csproj", "{884BA4AC-9170-49B1-BD6B-850B350C95C0}"
Project("{E53339B2-1760-4266-BCC7-CA923CBCF16C}") = "docker-compose", "docker-compose.dcproj", "{E305D5CD-E635-4268-9F74-D3FBE0DF16C8}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -103,14 +95,10 @@ Global
{D6BF9AE9-72FA-4726-A326-35A35D27FFB8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D6BF9AE9-72FA-4726-A326-35A35D27FFB8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D6BF9AE9-72FA-4726-A326-35A35D27FFB8}.Release|Any CPU.Build.0 = Release|Any CPU
{977C1053-9D63-4153-B61B-C3D2F1010F9F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{977C1053-9D63-4153-B61B-C3D2F1010F9F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{977C1053-9D63-4153-B61B-C3D2F1010F9F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{977C1053-9D63-4153-B61B-C3D2F1010F9F}.Release|Any CPU.Build.0 = Release|Any CPU
{884BA4AC-9170-49B1-BD6B-850B350C95C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{884BA4AC-9170-49B1-BD6B-850B350C95C0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{884BA4AC-9170-49B1-BD6B-850B350C95C0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{884BA4AC-9170-49B1-BD6B-850B350C95C0}.Release|Any CPU.Build.0 = Release|Any CPU
{E305D5CD-E635-4268-9F74-D3FBE0DF16C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E305D5CD-E635-4268-9F74-D3FBE0DF16C8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E305D5CD-E635-4268-9F74-D3FBE0DF16C8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E305D5CD-E635-4268-9F74-D3FBE0DF16C8}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -0,0 +1,45 @@
server {
listen 80;
server_name dev-services.damageasessment.net;
location /service1 {
rewrite /service1/(.*) /$1 break;
proxy_pass http://172.17.0.1:80/; # Replace with the address of your .NET Core application
}
location /service2 {
rewrite /service2/(.*) /$1 break;
proxy_pass http://172.17.0.1:80/; # Replace with the address of your .NET Core application
}
location /service3 {
rewrite /service3/(.*) /$1 break;
proxy_pass http://172.17.0.1:80/; # Replace with the address of your .NET Core application
}
location /service4 {
rewrite /service4/(.*) /$1 break;
proxy_pass http://172.17.0.1:80/; # Replace with the address of your .NET Core application
}
location /service5 {
rewrite /service5/(.*) /$1 break;
proxy_pass http://172.17.0.1:80/; # Replace with the address of your .NET Core application
}
location /service6 {
rewrite /service6/(.*) /$1 break;
proxy_pass http://172.17.0.1:80/; # Replace with the address of your .NET Core application
}
location /service7 {
rewrite /service7/(.*) /$1 break;
proxy_pass http://172.17.0.1:80/; # Replace with the address of your .NET Core application
}
}

View File

@ -0,0 +1,49 @@
server {
listen 80 default_server;
# server_name _;
root /var/www/html;
# Add index.php to the list if you are using PHP
# index index.html index.htm index.nginx-debian.html;
location /service1 {
rewrite /service1/(.*) /$1 break;
proxy_pass http://127.0.0.1:6001/; # Replace with the address of your .NET Core application
}
location /service2 {
rewrite /service2/(.*) /$1 break;
proxy_pass http://127.0.0.1:6002/; # Replace with the address of your .NET Core application
}
location /service3 {
rewrite /service3/(.*) /$1 break;
proxy_pass http://127.0.0.1:6003/; # Replace with the address of your .NET Core application
}
location /service4 {
rewrite /service4/(.*) /$1 break;
proxy_pass http://127.0.0.1:6004/; # Replace with the address of your .NET Core application
}
location /service5 {
rewrite /service5/(.*) /$1 break;
proxy_pass http://127.0.0.1:6005/; # Replace with the address of your .NET Core application
}
location /service6 {
rewrite /service6/(.*) /$1 break;
proxy_pass http://127.0.0.1:6006/; # Replace with the address of your .NET Core application
}
location /service7 {
rewrite /service7/(.*) /$1 break;
proxy_pass http://127.0.0.1:6007/; # Replace with the address of your .NET Core application
}
}

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" Sdk="Microsoft.Docker.Sdk">
<PropertyGroup Label="Globals">
<ProjectVersion>2.1</ProjectVersion>
<DockerTargetOS>Linux</DockerTargetOS>
<ProjectGuid>e305d5cd-e635-4268-9f74-d3fbe0df16c8</ProjectGuid>
<DockerLaunchAction>LaunchBrowser</DockerLaunchAction>
<DockerServiceUrl>{Scheme}://localhost:{ServicePort}/swagger</DockerServiceUrl>
<DockerServiceName>damageassesment.api.surveys</DockerServiceName>
</PropertyGroup>
<ItemGroup>
<None Include="docker-compose.override.yml">
<DependentUpon>docker-compose.yml</DependentUpon>
</None>
<None Include="docker-compose.yml" />
<None Include=".dockerignore" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,82 @@
version: '3.4'
services:
#nginx:
# container_name: my-nginx
# image: nginx:latest
# restart: always
# ports:
# - "80:80"
# volumes:
# - ./default.conf:/etc/nginx/conf.d/default.conf
damageassesment.api.answers:
environment:
- ASPNETCORE_ENVIRONMENT=Development
networks:
nginx-network:
ipv4_address: 172.18.0.150
ports:
- "6001:80"
damageassesment.api.attachments:
environment:
- ASPNETCORE_ENVIRONMENT=Development
networks:
nginx-network:
ipv4_address: 172.18.0.151
ports:
- "6002:80"
damageassesment.api.employees:
environment:
- ASPNETCORE_ENVIRONMENT=Development
networks:
nginx-network:
ipv4_address: 172.18.0.152
ports:
- "6003:80"
damageassesment.api.locations:
environment:
- ASPNETCORE_ENVIRONMENT=Development
networks:
nginx-network:
ipv4_address: 172.18.0.153
ports:
- "6004:80"
damageassesment.api.questions:
environment:
- ASPNETCORE_ENVIRONMENT=Development
networks:
nginx-network:
ipv4_address: 172.18.0.154
ports:
- "6005:80"
damageassesment.api.survey:
environment:
- ASPNETCORE_ENVIRONMENT=Development
networks:
nginx-network:
ipv4_address: 172.18.0.155
ports:
- "6006:80"
damageassesment.api.surveyresponses:
environment:
- ASPNETCORE_ENVIRONMENT=Development
- services__Answers=http://damageassesment.api.answers:80
- services__Locations=http://damageassesment.api.locations:80
- services__Questions=http://damageassesment.api.questions:80
- services__Employees=http://damageassesment.api.employees:80
- services__Attachments=http://damageassesment.api.attachments:80
- services__Surveys=http://damageassesment.api.survey:80
networks:
nginx-network:
ipv4_address: 172.18.0.156
ports:
- "6007:80"

View File

@ -0,0 +1,8 @@
version: '3.4'
services:
damageassesment.api.surveys:
image: ${DOCKER_REGISTRY-}damageassesmentapisurveys
build:
context: .
dockerfile: DamageAssesment.Api.Surveys/Dockerfile

View File

@ -0,0 +1,18 @@
{
"profiles": {
"Docker Compose": {
"commandName": "DockerCompose",
"commandVersion": "1.0",
"serviceActions": {
"damageassesment.api.answers": "StartDebugging",
"damageassesment.api.attachments": "StartDebugging",
"damageassesment.api.employees": "StartDebugging",
"damageassesment.api.locations": "StartDebugging",
"damageassesment.api.questions": "StartDebugging",
"damageassesment.api.survey": "StartDebugging",
"damageassesment.api.surveyresponses": "StartDebugging",
"damageassesment.api.surveys": "StartDebugging"
}
}
}
}