Commit 1551faff authored by hasan khaddour's avatar hasan khaddour

implment some of the Generics in the shared kernel.

parent 104902f3
using Microsoft.Extensions.Configuration; using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using PSManagement.Application.Common.Services; using PSManagement.Application.Common.Services;
using PSManagement.Application.Contracts.Authentication; using PSManagement.Application.Contracts.Authentication;
using PSManagement.Application.Contracts.Authorization;
using PSManagement.Infrastructure.Authentication; using PSManagement.Infrastructure.Authentication;
using PSManagement.Infrastructure.Persistence.Repositories.UserRepository;
using PSManagement.Infrastructure.Services; using PSManagement.Infrastructure.Services;
using PSManagement.Infrastructure.Services.Authentication; using PSManagement.Infrastructure.Services.Authentication;
using PSManagement.Infrastructure.Tokens;
namespace PSManagement.Infrastructure.DI namespace PSManagement.Infrastructure.DI
{ {
...@@ -12,12 +16,49 @@ namespace PSManagement.Infrastructure.DI ...@@ -12,12 +16,49 @@ namespace PSManagement.Infrastructure.DI
{ {
public static IServiceCollection AddInfrastructure(this IServiceCollection services,IConfiguration configuration) public static IServiceCollection AddInfrastructure(this IServiceCollection services,IConfiguration configuration)
{ {
services.Configure<JwtSetting>(configuration.GetSection(JwtSetting.Section)); services
services.AddSingleton<IJwtTokenGenerator,JwtTokenGenerator>(); .AddAuthentication(configuration)
.AddAuthorization()
.AddServices()
.AddPersistence();
return services;
}
private static IServiceCollection AddServices(this IServiceCollection services)
{
services.AddSingleton<IDateTimeProvider, DateTimeProvider>(); services.AddSingleton<IDateTimeProvider, DateTimeProvider>();
services.AddScoped<IAuthenticationService,AuthenticationService>();
return services;
}
private static IServiceCollection AddPersistence(this IServiceCollection services)
{
//services.AddDbContext<AppDbContext>(options => options.UseSqlite("Data Source = CleanArchitecture.sqlite"));
//services.AddScoped<IRemindersRepository, RemindersRepository>();
services.AddScoped<IUsersRepository, UsersRepository>();
return services;
}
private static IServiceCollection AddAuthorization(this IServiceCollection services)
{
return services; return services;
} }
private static IServiceCollection AddAuthentication(this IServiceCollection services, IConfiguration configuration)
{
services.Configure<JwtSetting>(configuration.GetSection(JwtSetting.Section));
services.AddSingleton<IJwtTokenGenerator, JwtTokenGenerator>();
services.AddScoped<IAuthenticationService, AuthenticationService>();
services
.ConfigureOptions<JwtBearerTokenValidationConfiguration>()
.AddAuthentication(defaultScheme: JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer();
return services;
}
} }
} }
...@@ -10,10 +10,15 @@ ...@@ -10,10 +10,15 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="5.0.17" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.17" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="5.0.17">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Configuration" Version="5.0.0" /> <PackageReference Include="Microsoft.Extensions.Configuration" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="5.0.2" /> <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="5.0.2" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="5.0.0" /> <PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="5.0.0" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="5.7.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
......
using System; using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
...@@ -6,7 +7,7 @@ using System.Threading.Tasks; ...@@ -6,7 +7,7 @@ using System.Threading.Tasks;
namespace PSManagement.Infrastructure.Common.Persistence namespace PSManagement.Infrastructure.Common.Persistence
{ {
public class AppDbContext public class AppDbContext : DbContext
{ {
} }
} }
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using PSManagement.Infrastructure.Common.Persistence;
using PSManagement.SharedKernel.Entities;
using PSManagement.SharedKernel.Interfaces;
using PSManagement.SharedKernel.Repositories;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PSManagement.Infrastructure.Persistence.Repositories.BaseRepository
{
public class BaseRepository<T> : IRepository<T> where T :BaseEntity
{
protected AppDbContext _dbContext;
internal DbSet<T> dbSet;
public BaseRepository(AppDbContext context)
{
_dbContext = context;
dbSet = context.Set<T>();
}
public async Task<T> AddAsync(T entity)
{
EntityEntry<T> entry = await dbSet.AddAsync(entity);
await _dbContext.SaveChangesAsync();
return entry.Entity;
}
public async Task<IEnumerable<T>> ListAsync()
{
return await dbSet.ToListAsync();
}
public async Task<IEnumerable<T>> ListAsync(ISpecification<T> specification)
{
var q = ApplySpecification(specification);
return await q.ToListAsync<T>();
}
public Task DeleteAsync(T entity)
{
_dbContext.Set<T>().Remove(entity);
return _dbContext.SaveChangesAsync();
}
public async Task<T> GetByIdAsync(int id, ISpecification<T> specification=null)
{
var q = ApplySpecification(specification);
return await q.SingleOrDefaultAsync(e => e.Id == id);
}
public async Task<T> UpdateAsync(T entity)
{
_dbContext.Entry(entity).State = EntityState.Modified;
await _dbContext.SaveChangesAsync();
return entity;
}
private IQueryable<T> ApplySpecification(ISpecification<T> specification)
{
return SpecificationEvaluator<T>.GetQuery(dbSet.AsQueryable(), specification);
}
}
}
using PSManagement.SharedKernel.Entities;
using PSManagement.SharedKernel.Interfaces;
using Microsoft.EntityFrameworkCore;
using System.Linq;
namespace PSManagement.Infrastructure.Persistence.Repositories.BaseRepository
{
public class SpecificationEvaluator<T> where T : BaseEntity
{
public static IQueryable<T> GetQuery(IQueryable<T> inputQuery, ISpecification<T> specification)
{
var query = inputQuery;
// modify the IQueryable using the specification's criteria expression
if (specification.Criteria != null)
{
query = query.Where(specification.Criteria);
}
// Includes all expression-based includes
query = specification.Includes.Aggregate(
query,
(current, include) => current.Include(include));
// Include any string-based include statements
query = specification.IncludeStrings.Aggregate(
query,
(current, include) => current.Include(include));
// Apply ordering if expressions are set
if (specification.OrderBy != null)
{
query = query.OrderBy(specification.OrderBy);
}
else if (specification.OrderByDescending != null)
{
query = query.OrderByDescending(specification.OrderByDescending);
}
//if (specification.GroupBy is not null)
//{
// query = query.GroupBy(specification.GroupBy).SelectMany(x => x);
//}
// Apply paging if enabled
if (specification.IsPagingEnabled)
{
query = query.Skip(specification.Skip)
.Take(specification.Take);
}
return query;
}
}
}
using PSManagement.Application.Contracts.Authentication;
using PSManagement.SharedKernel.Interfaces;
using PSManagement.SharedKernel.Repositories;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PSManagement.Infrastructure.Persistence.Repositories.UserRepository
{
public class UsersRepository : IUsersRepository
{
public static List<User> Users { get; set; } = new List<User>();
public async Task<User> AddAsync(User entity)
{
Users.Add(entity);
return entity;
}
public async Task DeleteAsync(User entity)
{
Users.Remove(entity);
}
public async Task<User> GetByEmail(string email)
{
return Users.Where(u => u.Email == email).FirstOrDefault();
}
public async Task<User> GetByIdAsync(int id, ISpecification<User> specification = null)
{
return Users.Where(u=>u.Id == id).FirstOrDefault();
}
public async Task<IEnumerable<User>> ListAsync()
{
return Users;
}
public async Task<IEnumerable<User>> ListAsync(ISpecification<User> spec)
{
return new List<User>();
}
public async Task<User> UpdateAsync(User entity)
{
return entity;
}
}
}
using PSManagement.Application.Contracts.Authentication; using PSManagement.Application.Contracts.Authentication;
using PSManagement.Application.Contracts.Authorization;
using PSManagement.SharedKernel.Utilities;
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
...@@ -7,37 +9,56 @@ namespace PSManagement.Infrastructure.Services.Authentication ...@@ -7,37 +9,56 @@ namespace PSManagement.Infrastructure.Services.Authentication
public class AuthenticationService :IAuthenticationService public class AuthenticationService :IAuthenticationService
{ {
private readonly IJwtTokenGenerator _jwtTokenGenerator; private readonly IJwtTokenGenerator _jwtTokenGenerator;
private readonly IUsersRepository _userRepository;
public AuthenticationService(IJwtTokenGenerator jwtTokenGenerator) public AuthenticationService(IJwtTokenGenerator jwtTokenGenerator, IUsersRepository userRepository)
{ {
_jwtTokenGenerator = jwtTokenGenerator; _jwtTokenGenerator = jwtTokenGenerator;
_userRepository = userRepository;
} }
public async Task<AuthenticationResult> Login(String email, String password) { public async Task<Result<AuthenticationResult>> Login(String email, String password) {
User u = await _userRepository.GetByEmail(email);
if (u is null || u.Password != password) {
return Result.Failure<AuthenticationResult>(new Error("404", "the password or email maybe wrong!."));
return new AuthenticationResult { }
Id = Guid.NewGuid(), String token = _jwtTokenGenerator.GenerateToken(u.Id,u.FirstName,u.LastName,u.Email);
Email=email,
FirstName="First name ", return Result.Success<AuthenticationResult>(
LastName ="last Name ", new AuthenticationResult {
Token="token" Id = u.Id,
Email=u.Email,
}; FirstName=u.FirstName,
LastName =u.LastName,
Token=token});
} }
public async Task<AuthenticationResult> Register(String email, String firstName, String lastName, String password) { public async Task<Result<AuthenticationResult>> Register(String email, String firstName, String lastName, String password) {
// check if the user exist // check if the user exist
var u = await _userRepository.GetByEmail(email);
Guid userId = Guid.NewGuid(); if (u is not null) {
return Result.Failure<AuthenticationResult>(new Error("404","the user already exist "));
}
await _userRepository.AddAsync(
new User{
Email=email ,
FirstName=firstName,
LastName=lastName,
Password=password
});
// generate token // generate token
String token = _jwtTokenGenerator.GenerateToken(userId,firstName,lastName,email); String token = _jwtTokenGenerator.GenerateToken(2322323,firstName,lastName,email);
return new AuthenticationResult return Result.Success<AuthenticationResult>(
new AuthenticationResult
{ {
Id = Guid.NewGuid(), Id = 233233,
Email = email, Email = email,
FirstName =firstName, FirstName = firstName,
LastName =lastName, LastName = lastName,
Token=token Token = token
}; });
} }
......
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using PSManagement.Infrastructure.Authentication;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PSManagement.Infrastructure.Tokens
{
public sealed class JwtBearerTokenValidationConfiguration
: IConfigureNamedOptions<JwtBearerOptions>
{
private readonly JwtSetting _jwtSettings ;
public JwtBearerTokenValidationConfiguration(IOptions<JwtSetting> jwtSettings)
{
_jwtSettings = jwtSettings.Value;
}
public void Configure(string? name, JwtBearerOptions options) => Configure(options);
public void Configure(JwtBearerOptions options)
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = _jwtSettings.Issuer,
ValidAudience = _jwtSettings.Audience,
IssuerSigningKey = new SymmetricSecurityKey(
Encoding.UTF8.GetBytes(_jwtSettings.Secret)),
};
}
}
}
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens; using Microsoft.IdentityModel.Tokens;
using PSManagement.Application.Common.Services; using PSManagement.Application.Common.Services;
using PSManagement.Application.Contracts.Authentication; using PSManagement.Application.Contracts.Authorization;
using System; using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt; using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims; using System.Security.Claims;
using System.Text; using System.Text;
using System.Threading.Tasks;
namespace PSManagement.Infrastructure.Authentication namespace PSManagement.Infrastructure.Authentication
{ {
...@@ -22,7 +19,7 @@ namespace PSManagement.Infrastructure.Authentication ...@@ -22,7 +19,7 @@ namespace PSManagement.Infrastructure.Authentication
_jwtSetting = jwtOptions.Value; _jwtSetting = jwtOptions.Value;
} }
public string GenerateToken(Guid id, string firstName, string lastName, string email) public string GenerateToken(int id, string firstName, string lastName, string email)
{ {
var signingCredentials = new SigningCredentials( var signingCredentials = new SigningCredentials(
new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtSetting.Secret)), new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtSetting.Secret)),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment