baseApplication, IMapper mapper) : base(baseApplication, mapper)
{
}
diff --git a/content/4.UI/Company.Project.UI/Data/main.sqlite b/content/4.UI/Company.Project.UI/Data/main.sqlite
index bf3d913..bf5867e 100644
Binary files a/content/4.UI/Company.Project.UI/Data/main.sqlite and b/content/4.UI/Company.Project.UI/Data/main.sqlite differ
diff --git a/content/4.UI/Company.Project.UI/Pages/Error.cshtml b/content/4.UI/Company.Project.UI/Pages/Error.cshtml
new file mode 100644
index 0000000..6f92b95
--- /dev/null
+++ b/content/4.UI/Company.Project.UI/Pages/Error.cshtml
@@ -0,0 +1,26 @@
+@page
+@model ErrorModel
+@{
+ ViewData["Title"] = "Error";
+}
+
+Error.
+An error occurred while processing your request.
+
+@if (Model.ShowRequestId)
+{
+
+ Request ID: @Model.RequestId
+
+}
+
+Development Mode
+
+ Swapping to the Development environment displays detailed information about the error that occurred.
+
+
+ The Development environment shouldn't be enabled for deployed applications.
+ It can result in displaying sensitive information from exceptions to end users.
+ For local debugging, enable the Development environment by setting the ASPNETCORE_ENVIRONMENT environment variable to Development
+ and restarting the app.
+
diff --git a/content/4.UI/Company.Project.UI/Pages/Error.cshtml.cs b/content/4.UI/Company.Project.UI/Pages/Error.cshtml.cs
new file mode 100644
index 0000000..f674af4
--- /dev/null
+++ b/content/4.UI/Company.Project.UI/Pages/Error.cshtml.cs
@@ -0,0 +1,41 @@
+using System.Diagnostics;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc.RazorPages;
+
+namespace Company.Project.UI.Pages;
+
+///
+/// Error Model Class
+///
+[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
+public class ErrorModel : PageModel
+{
+ private readonly ILogger _logger;
+
+ ///
+ /// Error Model Class Contructor
+ ///
+ ///
+ public ErrorModel(ILogger logger)
+ {
+ _logger = logger;
+ }
+
+ ///
+ /// Request Identifier.
+ /// /
+ public string? RequestId { get; set; }
+
+ ///
+ /// Bool that indicates if show Request Identifier when is available.
+ ///
+ public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
+
+ ///
+ /// On Get method that sets the Request Identifier
+ ///
+ public void OnGet()
+ {
+ RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
+ }
+}
diff --git a/content/4.UI/Company.Project.UI/Pages/_ViewImports.cshtml b/content/4.UI/Company.Project.UI/Pages/_ViewImports.cshtml
new file mode 100644
index 0000000..0758064
--- /dev/null
+++ b/content/4.UI/Company.Project.UI/Pages/_ViewImports.cshtml
@@ -0,0 +1,3 @@
+@using Company.Project.UI
+@namespace Company.Project.UI.Pages
+@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
diff --git a/content/4.UI/Company.Project.UI/Program.cs b/content/4.UI/Company.Project.UI/Program.cs
index 2255ae7..e4f5238 100644
--- a/content/4.UI/Company.Project.UI/Program.cs
+++ b/content/4.UI/Company.Project.UI/Program.cs
@@ -1,22 +1,18 @@
-using Company.Project.Domain.Entities.Config;
-using Company.Project.Infra.Data.Contexts;
+using System.Reflection;
+using System.Text;
+using Company.Project.Domain.Entities.Config;
using Company.Project.Infra.IoC.ConfigureServicesExtensions;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Mvc;
-using Microsoft.AspNetCore.SpaServices.AngularCli;
-using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
-using System.Reflection;
-using System.Text;
var builder = WebApplication.CreateBuilder(args);
var authConfig = builder.Configuration.GetSection(nameof(AuthConfig)).Get();
-var dbConfig = builder.Configuration.GetSection(nameof(DatabaseConfig)).Get();
-builder.Services.AddControllers();
-builder.Services.AddSpaStaticFiles(c => c.RootPath = "ClientApp/dist/ClientApp");
-builder.Services.AddDbContext(options => options.UseSqlite(dbConfig.ConnectionString), ServiceLifetime.Singleton);
+// Add services to the container.
+builder.Services.AddControllersWithViews();
+builder.Services.ConfigureAutoMapper();
builder.Services.ConfigureRepository();
builder.Services.ConfigureService();
builder.Services.ConfigureApplication();
@@ -24,10 +20,7 @@
{
options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
});
-builder.Services.Configure(x =>
- {
- x.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
- });
+
builder.Services.AddAuthentication(x =>
{
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
@@ -45,6 +38,7 @@
ValidateAudience = false
};
});
+
builder.Services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Microsoft.OpenApi.Models.OpenApiInfo { Title = "AppTitle API", Version = "v1" });
@@ -71,35 +65,32 @@
});
var app = builder.Build();
-if (app.Environment.IsDevelopment())
+
+// Configure the HTTP request pipeline.
+if (!app.Environment.IsDevelopment())
{
- app.UseDeveloperExceptionPage();
+ // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
+ app.UseHsts();
}
-else
+
+bool tryParse = Boolean.TryParse(Environment.GetEnvironmentVariable("ENABLE_SWAGGER"), out bool enableSwagger);
+
+if (app.Environment.IsDevelopment() || (tryParse && enableSwagger))
{
- app.UseHsts();
+ app.UseSwagger();
+ app.UseSwaggerUI();
}
+
app.UseHttpsRedirection();
app.UseStaticFiles();
-app.UseSpaStaticFiles();
app.UseAuthentication();
app.UseRouting();
app.UseAuthorization();
-app.UseEndpoints(endpoints => endpoints.MapControllers());
-app.UseSwagger();
-app.UseSwaggerUI(c =>
-{
- c.SwaggerEndpoint("/swagger/v1/swagger.json", "AppTitle V1");
-});
+app.MapControllerRoute(
+ name: "default",
+ pattern: "{controller}/{action=Index}/{id?}");
-app.UseSpa(spa =>
-{
- spa.Options.SourcePath = "ClientApp";
- if (app.Environment.IsDevelopment())
- {
- spa.UseAngularCliServer(npmScript: "start");
- }
-});
+app.MapFallbackToFile("index.html"); ;
app.Run();
diff --git a/content/4.UI/Company.Project.UI/Properties/launchSettings.json b/content/4.UI/Company.Project.UI/Properties/launchSettings.json
index 5918195..5e93dda 100644
--- a/content/4.UI/Company.Project.UI/Properties/launchSettings.json
+++ b/content/4.UI/Company.Project.UI/Properties/launchSettings.json
@@ -1,30 +1,29 @@
{
- "$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
- "windowsAuthentication": false,
- "anonymousAuthentication": true,
+ "windowsAuthentication": false,
+ "anonymousAuthentication": true,
"iisExpress": {
- "applicationUrl": "http://localhost:44218",
- "sslPort": 44362
+ "applicationUrl": "http://localhost:58460",
+ "sslPort": 44348
}
},
"profiles": {
- "IIS Express": {
- "commandName": "IISExpress",
+ "Company.Project.UI": {
+ "commandName": "Project",
"launchBrowser": true,
- "launchUrl": "swagger",
+ "applicationUrl": "https://localhost:7134;http://localhost:5085",
"environmentVariables": {
- "ASPNETCORE_ENVIRONMENT": "Development"
+ "ASPNETCORE_ENVIRONMENT": "Development",
+ "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.SpaProxy"
}
},
- "Company.Project.UI": {
- "commandName": "Project",
+ "IIS Express": {
+ "commandName": "IISExpress",
"launchBrowser": true,
- "launchUrl": "swagger",
- "applicationUrl": "http://localhost:5000",
"environmentVariables": {
- "ASPNETCORE_ENVIRONMENT": "Development"
+ "ASPNETCORE_ENVIRONMENT": "Development",
+ "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.SpaProxy"
}
}
}
-}
\ No newline at end of file
+}
diff --git a/content/4.UI/Company.Project.UI/Startup.cs b/content/4.UI/Company.Project.UI/Startup.cs
deleted file mode 100644
index 0ee0f87..0000000
--- a/content/4.UI/Company.Project.UI/Startup.cs
+++ /dev/null
@@ -1,144 +0,0 @@
-namespace Company.Project.UI
-{
- using Domain.Entities.Config;
- using Infra.Data.Contexts;
- using Infra.IoC.ConfigureServicesExtensions;
- using Microsoft.AspNetCore.Authentication.JwtBearer;
- using Microsoft.AspNetCore.Builder;
- using Microsoft.AspNetCore.Hosting;
- using Microsoft.AspNetCore.Mvc;
- using Microsoft.AspNetCore.SpaServices.AngularCli;
- using Microsoft.EntityFrameworkCore;
- using Microsoft.Extensions.Configuration;
- using Microsoft.Extensions.DependencyInjection;
- using Microsoft.Extensions.Hosting;
- using Microsoft.IdentityModel.Tokens;
- using System;
- using System.IO;
- using System.Reflection;
- using System.Text;
-
- ///
- /// Startup class.
- ///
- public class Startup
- {
- ///
- /// Initializes a new instance of the class.
- ///
- /// The configuration.
- public Startup(IConfiguration configuration)
- {
- Configuration = configuration;
- }
-
- ///
- /// Gets the configuration.
- ///
- ///
- /// The configuration.
- ///
- public IConfiguration Configuration { get; }
-
- ///
- /// Configures the services.
- /// This method gets called by the runtime. Use this method to add services to the container.
- ///
- /// The services.
- public void ConfigureServices(IServiceCollection services)
- {
- var authConfig = Configuration.GetSection(nameof(AuthConfig)).Get();
- var dbConfig = Configuration.GetSection(nameof(DatabaseConfig)).Get();
-
- services.AddControllers();
- services.AddSpaStaticFiles(c => c.RootPath = "ClientApp/dist/ClientApp");
- services.AddDbContext(options => options.UseSqlite(dbConfig.ConnectionString), ServiceLifetime.Singleton);
- services.ConfigureRepository();
- services.ConfigureService();
- services.ConfigureApplication();
- services.Configure(x =>
- {
- x.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
- });
- services.AddAuthentication(x =>
- {
- x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
- x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
- })
- .AddJwtBearer(x =>
- {
- x.RequireHttpsMetadata = false;
- x.SaveToken = true;
- x.TokenValidationParameters = new TokenValidationParameters
- {
- ValidateIssuerSigningKey = true,
- IssuerSigningKey = new SymmetricSecurityKey(Encoding.Default.GetBytes(authConfig.Key)),
- ValidateIssuer = false,
- ValidateAudience = false
- };
- });
- services.AddSwaggerGen(c =>
- {
- c.SwaggerDoc("v1", new Microsoft.OpenApi.Models.OpenApiInfo { Title = "AppTitle API", Version = "v1" });
- var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
- var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
- c.IncludeXmlComments(xmlPath);
- var inasd = (Microsoft.OpenApi.Models.ParameterLocation) authConfig.In;
- var scheme = new Microsoft.OpenApi.Models.OpenApiSecurityScheme
- {
- Description = authConfig.Description,
- Name = authConfig.Name,
- In = (Microsoft.OpenApi.Models.ParameterLocation) authConfig.In,
- Type = (Microsoft.OpenApi.Models.SecuritySchemeType) authConfig.Type,
- Reference = new Microsoft.OpenApi.Models.OpenApiReference {
- Id = JwtBearerDefaults.AuthenticationScheme,
- Type = Microsoft.OpenApi.Models.ReferenceType.SecurityScheme
- }
- };
- c.AddSecurityDefinition(scheme.Reference.Id, scheme);
- c.AddSecurityRequirement(new Microsoft.OpenApi.Models.OpenApiSecurityRequirement {
- { scheme, Array.Empty() }
- });
- });
- }
-
- ///
- /// Configures the specified application.
- /// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
- ///
- /// The application.
- /// The env.
- public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
- {
- if (env.IsDevelopment())
- {
- app.UseDeveloperExceptionPage();
- }
- else
- {
- app.UseHsts();
- }
- app.UseHttpsRedirection();
- app.UseStaticFiles();
- app.UseSpaStaticFiles();
- app.UseAuthentication();
- app.UseRouting();
- app.UseAuthorization();
- app.UseEndpoints(endpoints => endpoints.MapControllers());
-
- app.UseSwagger();
- app.UseSwaggerUI(c =>
- {
- c.SwaggerEndpoint("/swagger/v1/swagger.json", "AppTitle V1");
- });
-
- app.UseSpa(spa => {
- spa.Options.SourcePath = "ClientApp";
- if (env.IsDevelopment())
- {
- spa.UseAngularCliServer(npmScript: "start");
- }
- });
- }
- }
-}
diff --git a/content/4.UI/Company.Project.UI/ValidateClaim/ValidateClaimAttribute.cs b/content/4.UI/Company.Project.UI/ValidateClaim/ValidateClaimAttribute.cs
index da558ad..81c469c 100644
--- a/content/4.UI/Company.Project.UI/ValidateClaim/ValidateClaimAttribute.cs
+++ b/content/4.UI/Company.Project.UI/ValidateClaim/ValidateClaimAttribute.cs
@@ -39,7 +39,8 @@ public void OnAuthorization(AuthorizationFilterContext context)
{
var controller = (context.ActionDescriptor as ControllerActionDescriptor)!.ControllerName.ToLower();
var claimValue = this.Template.Replace("[controller]", controller);
- if (context.HttpContext.User.HasClaim(claim =>
+ var isAdmin = context.HttpContext.User.HasClaim(claim => claim.Type == CustomClaimTypes.IsAdmin && bool.Parse(claim.Value));
+ if (isAdmin || context.HttpContext.User.HasClaim(claim =>
claim.Type == CustomClaimTypes.Permission && claim.Value == claimValue))
{
return;
diff --git a/content/4.UI/Company.Project.UI/appsettings.Development.json b/content/4.UI/Company.Project.UI/appsettings.Development.json
index e203e94..84308c9 100644
--- a/content/4.UI/Company.Project.UI/appsettings.Development.json
+++ b/content/4.UI/Company.Project.UI/appsettings.Development.json
@@ -1,9 +1,10 @@
{
"Logging": {
"LogLevel": {
- "Default": "Debug",
- "System": "Information",
- "Microsoft": "Information"
+ "Default": "Information",
+ "Microsoft": "Warning",
+ "Microsoft.AspNetCore.SpaProxy": "Information",
+ "Microsoft.Hosting.Lifetime": "Information"
}
}
}
diff --git a/content/4.UI/Company.Project.UI/appsettings.json b/content/4.UI/Company.Project.UI/appsettings.json
index e4a7d90..478f376 100644
--- a/content/4.UI/Company.Project.UI/appsettings.json
+++ b/content/4.UI/Company.Project.UI/appsettings.json
@@ -1,7 +1,9 @@
{
"Logging": {
"LogLevel": {
- "Default": "Warning"
+ "Default": "Information",
+ "Microsoft": "Warning",
+ "Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
@@ -23,4 +25,4 @@
"Password": "eb09998bf9569d19ac2a78eacd956469",
"Sender": "jsmontoya@soyucn.edu.co"
}
-}
\ No newline at end of file
+}
diff --git a/content/4.UI/Company.Project.UI/wwwroot/favicon.ico b/content/4.UI/Company.Project.UI/wwwroot/favicon.ico
new file mode 100644
index 0000000..63e859b
Binary files /dev/null and b/content/4.UI/Company.Project.UI/wwwroot/favicon.ico differ