diff --git a/src/Tests/Web.Api.Core.UnitTests/Web.Api.Core.UnitTests.csproj b/src/Tests/Web.Api.Core.UnitTests/Web.Api.Core.UnitTests.csproj index d1c70b4..b5a1961 100644 --- a/src/Tests/Web.Api.Core.UnitTests/Web.Api.Core.UnitTests.csproj +++ b/src/Tests/Web.Api.Core.UnitTests/Web.Api.Core.UnitTests.csproj @@ -1,16 +1,19 @@ - netcoreapp2.1 + netcoreapp3.0 false - - - - + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/src/Tests/Web.Api.UnitTests/Presenters/LoginPresenterUnitTests.cs b/src/Tests/Web.Api.UnitTests/Presenters/LoginPresenterUnitTests.cs index e3bc21c..b375689 100644 --- a/src/Tests/Web.Api.UnitTests/Presenters/LoginPresenterUnitTests.cs +++ b/src/Tests/Web.Api.UnitTests/Presenters/LoginPresenterUnitTests.cs @@ -36,7 +36,7 @@ public void Contains_Token_When_Use_Case_Succeeds() // assert dynamic data = JsonConvert.DeserializeObject(presenter.ContentResult.Content); - Assert.Equal(authToken, data.authtoken.Value); + Assert.Equal(authToken, data.authToken.Value); } [Fact] diff --git a/src/Tests/Web.Api.UnitTests/Web.Api.UnitTests.csproj b/src/Tests/Web.Api.UnitTests/Web.Api.UnitTests.csproj index 8690732..71878d2 100644 --- a/src/Tests/Web.Api.UnitTests/Web.Api.UnitTests.csproj +++ b/src/Tests/Web.Api.UnitTests/Web.Api.UnitTests.csproj @@ -1,17 +1,19 @@ - netcoreapp2.1 + netcoreapp3.0 false - - - - - + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/src/Web.Api.Core/Web.Api.Core.csproj b/src/Web.Api.Core/Web.Api.Core.csproj index 9ec609f..1092a52 100644 --- a/src/Web.Api.Core/Web.Api.Core.csproj +++ b/src/Web.Api.Core/Web.Api.Core.csproj @@ -1,11 +1,11 @@ - netcoreapp2.1 + netcoreapp3.0 - + diff --git a/src/Web.Api.Infrastructure/Web.Api.Infrastructure.csproj b/src/Web.Api.Infrastructure/Web.Api.Infrastructure.csproj index 3dae87e..50e3069 100644 --- a/src/Web.Api.Infrastructure/Web.Api.Infrastructure.csproj +++ b/src/Web.Api.Infrastructure/Web.Api.Infrastructure.csproj @@ -1,28 +1,30 @@  - netcoreapp2.1 + netcoreapp3.0 - - - - - - - - - - - - + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + - - System - diff --git a/src/Web.Api/Startup.cs b/src/Web.Api/Startup.cs index 902117a..88b1671 100644 --- a/src/Web.Api/Startup.cs +++ b/src/Web.Api/Startup.cs @@ -16,7 +16,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; using Microsoft.IdentityModel.Tokens; +using Microsoft.OpenApi.Models; using Swashbuckle.AspNetCore.Swagger; using Web.Api.Core; using Web.Api.Extensions; @@ -28,141 +30,141 @@ namespace Web.Api { - public class Startup - { - private const string SecretKey = "iNivDmHLpUA223sqsfhqGbMRdRj1PVkH"; // todo: get this from somewhere secure - private readonly SymmetricSecurityKey _signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(SecretKey)); - - public Startup(IConfiguration configuration) + public class Startup { - Configuration = configuration; - } + private const string SecretKey = "iNivDmHLpUA223sqsfhqGbMRdRj1PVkH"; // todo: get this from somewhere secure + private readonly SymmetricSecurityKey _signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(SecretKey)); - public IConfiguration Configuration { get; } + public Startup(IConfiguration configuration) + { + Configuration = configuration; + } - // This method gets called by the runtime. Use this method to add services to the container. - public IServiceProvider ConfigureServices(IServiceCollection services) - { - // Add framework services. - services.AddDbContext(options => options.UseSqlServer(Configuration.GetConnectionString("Default"), b => b.MigrationsAssembly("Web.Api.Infrastructure"))); - - // jwt wire up - // Get options from app settings - var jwtAppSettingOptions = Configuration.GetSection(nameof(JwtIssuerOptions)); - - // Configure JwtIssuerOptions - services.Configure(options => - { - options.Issuer = jwtAppSettingOptions[nameof(JwtIssuerOptions.Issuer)]; - options.Audience = jwtAppSettingOptions[nameof(JwtIssuerOptions.Audience)]; - options.SigningCredentials = new SigningCredentials(_signingKey, SecurityAlgorithms.HmacSha256); - }); - - var tokenValidationParameters = new TokenValidationParameters - { - ValidateIssuer = true, - ValidIssuer = jwtAppSettingOptions[nameof(JwtIssuerOptions.Issuer)], - - ValidateAudience = true, - ValidAudience = jwtAppSettingOptions[nameof(JwtIssuerOptions.Audience)], - - ValidateIssuerSigningKey = true, - IssuerSigningKey = _signingKey, - - RequireExpirationTime = false, - ValidateLifetime = true, - ClockSkew = TimeSpan.Zero - }; - - services.AddAuthentication(options => - { - options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; - options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; - - }).AddJwtBearer(configureOptions => - { - configureOptions.ClaimsIssuer = jwtAppSettingOptions[nameof(JwtIssuerOptions.Issuer)]; - configureOptions.TokenValidationParameters = tokenValidationParameters; - configureOptions.SaveToken = true; - }); - - // add identity - var identityBuilder = services.AddIdentityCore(o => + public IConfiguration Configuration { get; } + + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + public void Configure(IApplicationBuilder app, IWebHostEnvironment env) + { + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } + + app.UseExceptionHandler( + builder => + { + builder.Run( + async context => + { + context.Response.StatusCode = (int)HttpStatusCode.InternalServerError; + context.Response.Headers.Add("Access-Control-Allow-Origin", "*"); + + var error = context.Features.Get(); + if (error != null) + { + context.Response.AddApplicationError(error.Error.Message); + await context.Response.WriteAsync(error.Error.Message).ConfigureAwait(false); + } + }); + }); + + // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.), specifying the Swagger + // JSON endpoint. + app.UseSwaggerUI(c => { - // configure identity options - o.Password.RequireDigit = false; - o.Password.RequireLowercase = false; - o.Password.RequireUppercase = false; - o.Password.RequireNonAlphanumeric = false; - o.Password.RequiredLength = 6; + c.SwaggerEndpoint("/swagger/v1/swagger.json", "CleanAspNetCoreWebAPI V1"); }); - identityBuilder = new IdentityBuilder(identityBuilder.UserType, typeof(IdentityRole), identityBuilder.Services); - identityBuilder.AddEntityFrameworkStores().AddDefaultTokenProviders(); + // Enable middleware to serve generated Swagger as a JSON endpoint. + app.UseSwagger(); - services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1).AddFluentValidation(fv => fv.RegisterValidatorsFromAssemblyContaining()); + app.UseMvc(); + } - services.AddAutoMapper(); + // This method gets called by the runtime. Use this method to add services to the container. + public IServiceProvider ConfigureServices(IServiceCollection services) + { + // Add framework services. + services.AddDbContext(options => options.UseSqlServer(Configuration.GetConnectionString("Default"), b => b.MigrationsAssembly("Web.Api.Infrastructure"))); - // Register the Swagger generator, defining 1 or more Swagger documents - services.AddSwaggerGen(c => - { - c.SwaggerDoc("v1", new Info { Title = "CleanAspNetCoreWebAPI", Version = "v1" }); - }); + // jwt wire up Get options from app settings + var jwtAppSettingOptions = Configuration.GetSection(nameof(JwtIssuerOptions)); - // Now register our services with Autofac container. - var builder = new ContainerBuilder(); + // Configure JwtIssuerOptions + services.Configure(options => + { + options.Issuer = jwtAppSettingOptions[nameof(JwtIssuerOptions.Issuer)]; + options.Audience = jwtAppSettingOptions[nameof(JwtIssuerOptions.Audience)]; + options.SigningCredentials = new SigningCredentials(_signingKey, SecurityAlgorithms.HmacSha256); + }); - builder.RegisterModule(new CoreModule()); - builder.RegisterModule(new InfrastructureModule()); + var tokenValidationParameters = new TokenValidationParameters + { + ValidateIssuer = true, + ValidIssuer = jwtAppSettingOptions[nameof(JwtIssuerOptions.Issuer)], - // Presenters - builder.RegisterType().SingleInstance(); - builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()).Where(t => t.Name.EndsWith("Presenter")).SingleInstance(); + ValidateAudience = true, + ValidAudience = jwtAppSettingOptions[nameof(JwtIssuerOptions.Audience)], - builder.Populate(services); - var container = builder.Build(); - // Create the IServiceProvider based on the container. - return new AutofacServiceProvider(container); - } + ValidateIssuerSigningKey = true, + IssuerSigningKey = _signingKey, - // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IHostingEnvironment env) - { - if (env.IsDevelopment()) - { - app.UseDeveloperExceptionPage(); - } - - app.UseExceptionHandler( - builder => - { - builder.Run( - async context => - { - context.Response.StatusCode = (int)HttpStatusCode.InternalServerError; - context.Response.Headers.Add("Access-Control-Allow-Origin", "*"); - - var error = context.Features.Get(); - if (error != null) - { - context.Response.AddApplicationError(error.Error.Message); - await context.Response.WriteAsync(error.Error.Message).ConfigureAwait(false); - } + RequireExpirationTime = false, + ValidateLifetime = true, + ClockSkew = TimeSpan.Zero + }; + + services.AddAuthentication(options => + { + options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; + options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; + }).AddJwtBearer(configureOptions => + { + configureOptions.ClaimsIssuer = jwtAppSettingOptions[nameof(JwtIssuerOptions.Issuer)]; + configureOptions.TokenValidationParameters = tokenValidationParameters; + configureOptions.SaveToken = true; + }); + + // add identity + var identityBuilder = services.AddIdentityCore(o => + { + // configure identity options + o.Password.RequireDigit = false; + o.Password.RequireLowercase = false; + o.Password.RequireUppercase = false; + o.Password.RequireNonAlphanumeric = false; + o.Password.RequiredLength = 6; }); - }); - // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.), - // specifying the Swagger JSON endpoint. - app.UseSwaggerUI(c => - { - c.SwaggerEndpoint("/swagger/v1/swagger.json", "CleanAspNetCoreWebAPI V1"); - }); + identityBuilder = new IdentityBuilder(identityBuilder.UserType, typeof(IdentityRole), identityBuilder.Services); + identityBuilder.AddEntityFrameworkStores().AddDefaultTokenProviders(); + + services.AddMvc(options => options.EnableEndpointRouting = false) + .SetCompatibilityVersion(CompatibilityVersion.Latest) + .AddFluentValidation(fv => fv.RegisterValidatorsFromAssemblyContaining()); + + services.AddAutoMapper(typeof(Startup)); + + // Register the Swagger generator, defining 1 or more Swagger documents + services.AddSwaggerGen(c => + { + c.SwaggerDoc("v1", new OpenApiInfo { Title = "CleanAspNetCoreWebAPI", Version = "v1" }); + }); + + // Now register our services with Autofac container. + var builder = new ContainerBuilder(); + + builder.RegisterModule(new CoreModule()); + builder.RegisterModule(new InfrastructureModule()); - // Enable middleware to serve generated Swagger as a JSON endpoint. - app.UseSwagger(); + // Presenters + builder.RegisterType().SingleInstance(); + builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()).Where(t => t.Name.EndsWith("Presenter")).SingleInstance(); - app.UseMvc(); + builder.Populate(services); + var container = builder.Build(); + // Create the IServiceProvider based on the container. + return new AutofacServiceProvider(container); + } } - } -} +} \ No newline at end of file diff --git a/src/Web.Api/Web.Api.csproj b/src/Web.Api/Web.Api.csproj index 9497da0..b21e40c 100644 --- a/src/Web.Api/Web.Api.csproj +++ b/src/Web.Api/Web.Api.csproj @@ -1,7 +1,7 @@ - netcoreapp2.1 + netcoreapp3.0 @@ -9,11 +9,11 @@ - - - - - + + + + +