Skip to content

Commit

Permalink
Migrating to .NET 3.1
Browse files Browse the repository at this point in the history
  • Loading branch information
EduardoPires committed Jan 23, 2020
1 parent 7a4d681 commit 52919d9
Show file tree
Hide file tree
Showing 16 changed files with 747 additions and 0 deletions.
10 changes: 10 additions & 0 deletions src/Equinox.Services.Api/Configurations/AppSettings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace Equinox.Services.Api.Configurations
{
public class AppSettings
{
public string Secret { get; set; }
public int Expiration { get; set; }
public string Issuer { get; set; }
public string ValidAt { get; set; }
}
}
17 changes: 17 additions & 0 deletions src/Equinox.Services.Api/Configurations/AutoMapperSetup.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System;
using AutoMapper;
using Equinox.Application.AutoMapper;
using Microsoft.Extensions.DependencyInjection;

namespace Equinox.Services.Api.Configurations
{
public static class AutoMapperSetup
{
public static void AddAutoMapperSetup(this IServiceCollection services)
{
if (services == null) throw new ArgumentNullException(nameof(services));

services.AddAutoMapper(typeof(DomainToViewModelMappingProfile), typeof(ViewModelToDomainMappingProfile));
}
}
}
26 changes: 26 additions & 0 deletions src/Equinox.Services.Api/Configurations/DatabaseSetup.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System;
using Equinox.Infra.CrossCutting.Identity.Models;
using Equinox.Infra.Data.Context;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace Equinox.Services.Api.Configurations
{
public static class DatabaseSetup
{
public static void AddDatabaseSetup(this IServiceCollection services, IConfiguration configuration)
{
if (services == null) throw new ArgumentNullException(nameof(services));

services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(configuration.GetConnectionString("DefaultConnection")));

services.AddDbContext<EquinoxContext>(options =>
options.UseSqlServer(configuration.GetConnectionString("DefaultConnection")));

services.AddDbContext<EventStoreSqlContext>(options =>
options.UseSqlServer(configuration.GetConnectionString("DefaultConnection")));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System;
using Equinox.Infra.CrossCutting.IoC;
using Microsoft.Extensions.DependencyInjection;

namespace Equinox.Services.Api.Configurations
{
public static class DependencyInjectionSetup
{
public static void AddDependencyInjectionSetup(this IServiceCollection services)
{
if (services == null) throw new ArgumentNullException(nameof(services));

NativeInjectorBootStrapper.RegisterServices(services);
}
}
}
71 changes: 71 additions & 0 deletions src/Equinox.Services.Api/Configurations/IdentitySetup.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
using System;
using System.Text;
using Equinox.Infra.CrossCutting.Identity.Authorization;
using Equinox.Infra.CrossCutting.Identity.Models;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;

namespace Equinox.Services.Api.Configurations
{
public static class IdentitySetup
{
public static void AddIdentitySetup(this IServiceCollection services, IConfiguration configuration)
{
if (services == null) throw new ArgumentNullException(nameof(services));

services.AddDefaultIdentity<IdentityUser>()
.AddRoles<IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();

// JWT Setup

var appSettingsSection = configuration.GetSection("AppSettings");
services.Configure<AppSettings>(appSettingsSection);

var appSettings = appSettingsSection.Get<AppSettings>();
var key = Encoding.ASCII.GetBytes(appSettings.Secret);

services.AddAuthentication(x =>
{
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(x =>
{
x.RequireHttpsMetadata = true;
x.SaveToken = true;
x.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = true,
ValidateAudience = true,
ValidAudience = appSettings.ValidAt,
ValidIssuer = appSettings.Issuer
};
});

services.AddAuthorization(options =>
{
var defaultAuthorizationPolicyBuilder = new AuthorizationPolicyBuilder(JwtBearerDefaults.AuthenticationScheme);
defaultAuthorizationPolicyBuilder = defaultAuthorizationPolicyBuilder.RequireAuthenticatedUser();
options.DefaultPolicy = defaultAuthorizationPolicyBuilder.Build();
});
}

public static void AddAuthSetup(this IServiceCollection services, IConfiguration configuration)
{
if (services == null) throw new ArgumentNullException(nameof(services));

services.AddAuthorization(options =>
{
options.AddPolicy("CanWriteCustomerData", policy => policy.Requirements.Add(new ClaimRequirement("Customers", "Write")));
options.AddPolicy("CanRemoveCustomerData", policy => policy.Requirements.Add(new ClaimRequirement("Customers", "Remove")));
});
}
}
}
68 changes: 68 additions & 0 deletions src/Equinox.Services.Api/Configurations/SwaggerSetup.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;

namespace Equinox.Services.Api.Configurations
{
public static class SwaggerSetup
{
public static void AddSwaggerSetup(this IServiceCollection services)
{
if (services == null) throw new ArgumentNullException(nameof(services));

services.AddSwaggerGen(s =>
{
s.SwaggerDoc("v1", new OpenApiInfo
{
Version = "v1",
Title = "Equinox Project",
Description = "Equinox API Swagger surface",
Contact = new OpenApiContact { Name = "Eduardo Pires", Email = "[email protected]", Url = new Uri("http://www.eduardopires.net.br") },
License = new OpenApiLicense() { Name = "MIT", Url = new Uri("https://github.com/EduardoPires/EquinoxProject/blob/master/LICENSE") }
});

s.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"",
Name = "Authorization",
In = ParameterLocation.Header,
Type = SecuritySchemeType.ApiKey,
Scheme = "Bearer"
});

s.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "Bearer"
},
Scheme = "oauth2",
Name = "Bearer",
In = ParameterLocation.Header,

},
new List<string>()
}
});

});
}

public static void UseSwaggerSetup(this IApplicationBuilder app)
{
if (app == null) throw new ArgumentNullException(nameof(app));

app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "Equinox Project");
});
}
}
}
120 changes: 120 additions & 0 deletions src/Equinox.Services.Api/Controllers/AccountController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
using System;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using Equinox.Domain.Core.Bus;
using Equinox.Domain.Core.Notifications;
using Equinox.Infra.CrossCutting.Identity.Models;
using Equinox.Services.Api.Configurations;
using MediatR;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;

namespace Equinox.Services.Api.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class AccountController : ApiController
{
private readonly SignInManager<IdentityUser> _signInManager;
private readonly UserManager<IdentityUser> _userManager;
private readonly AppSettings _appSettings;

public AccountController(
SignInManager<IdentityUser> signInManager,
UserManager<IdentityUser> userManager,
IOptions<AppSettings> appSettings,
INotificationHandler<DomainNotification> notifications,
IMediatorHandler mediator) : base(notifications, mediator)
{
_userManager = userManager;
_signInManager = signInManager;
_appSettings = appSettings.Value;
}

[HttpPost]
[Route("register")]
public async Task<IActionResult> Register(UserRegistration userRegistration)
{
if (!ModelState.IsValid)
{
NotifyModelStateErrors();
return Response(userRegistration);
}

var user = new IdentityUser
{
UserName = userRegistration.Email,
Email = userRegistration.Email,
EmailConfirmed = true
};

var result = await _userManager.CreateAsync(user, userRegistration.Password);

if (!result.Succeeded)
{
foreach (var error in result.Errors)
{
NotifyError(error.Code, error.Description);
}

return Response(userRegistration);
}

await _signInManager.SignInAsync(user, false);
var token = await GenerateJwt(userRegistration.Email);

return Response(token);
}

[HttpPost]
[Route("login")]
public async Task<IActionResult> Login(UserLogin userLogin)
{
if (!ModelState.IsValid)
{
NotifyModelStateErrors();
return Response(userLogin);
}

var result = await _signInManager.PasswordSignInAsync(userLogin.Email, userLogin.Password, false, true);

if (result.Succeeded)
{
var token = await GenerateJwt(userLogin.Email);
return Response(token);
}

NotifyError("Login", result.ToString());
return Response(userLogin);
}

private async Task<string> GenerateJwt(string email)
{
var user = await _userManager.FindByEmailAsync(email);
var claims = await _userManager.GetClaimsAsync(user);

claims.Add(new Claim(JwtRegisteredClaimNames.Sub, user.Id));
claims.Add(new Claim(JwtRegisteredClaimNames.Email, user.Email));

var identityClaims = new ClaimsIdentity();
identityClaims.AddClaims(claims);

var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.ASCII.GetBytes(_appSettings.Secret);
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = identityClaims,
Issuer = _appSettings.Issuer,
Audience = _appSettings.ValidAt,
Expires = DateTime.UtcNow.AddHours(_appSettings.Expiration),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
};

return tokenHandler.WriteToken(tokenHandler.CreateToken(tokenDescriptor));
}
}
}
Loading

0 comments on commit 52919d9

Please sign in to comment.