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 PSManagement.Application.Common.Services;
using PSManagement.Application.Contracts.Authentication;
using PSManagement.Application.Contracts.Authorization;
using PSManagement.Infrastructure.Authentication;
using PSManagement.Infrastructure.Persistence.Repositories.UserRepository;
using PSManagement.Infrastructure.Services;
using PSManagement.Infrastructure.Services.Authentication;
using PSManagement.Infrastructure.Tokens;
namespace PSManagement.Infrastructure.DI
{
......@@ -12,12 +16,49 @@ namespace PSManagement.Infrastructure.DI
{
public static IServiceCollection AddInfrastructure(this IServiceCollection services,IConfiguration configuration)
{
services.Configure<JwtSetting>(configuration.GetSection(JwtSetting.Section));
services.AddSingleton<IJwtTokenGenerator,JwtTokenGenerator>();
services
.AddAuthentication(configuration)
.AddAuthorization()
.AddServices()
.AddPersistence();
return services;
}
private static IServiceCollection AddServices(this IServiceCollection services)
{
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;
}
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 @@
</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.DependencyInjection" Version="5.0.2" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="5.0.0" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="5.7.0" />
</ItemGroup>
<ItemGroup>
......
using System;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
......@@ -6,7 +7,7 @@ using System.Threading.Tasks;
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.Authorization;
using PSManagement.SharedKernel.Utilities;
using System;
using System.Threading.Tasks;
......@@ -7,37 +9,56 @@ namespace PSManagement.Infrastructure.Services.Authentication
public class AuthenticationService :IAuthenticationService
{
private readonly IJwtTokenGenerator _jwtTokenGenerator;
private readonly IUsersRepository _userRepository;
public AuthenticationService(IJwtTokenGenerator jwtTokenGenerator)
public AuthenticationService(IJwtTokenGenerator jwtTokenGenerator, IUsersRepository userRepository)
{
_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(),
Email=email,
FirstName="First name ",
LastName ="last Name ",
Token="token"
};
}
String token = _jwtTokenGenerator.GenerateToken(u.Id,u.FirstName,u.LastName,u.Email);
return Result.Success<AuthenticationResult>(
new AuthenticationResult {
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
Guid userId = Guid.NewGuid();
var u = await _userRepository.GetByEmail(email);
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
String token = _jwtTokenGenerator.GenerateToken(userId,firstName,lastName,email);
return new AuthenticationResult
String token = _jwtTokenGenerator.GenerateToken(2322323,firstName,lastName,email);
return Result.Success<AuthenticationResult>(
new AuthenticationResult
{
Id = Guid.NewGuid(),
Id = 233233,
Email = email,
FirstName =firstName,
LastName =lastName,
Token=token
};
FirstName = firstName,
LastName = lastName,
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.IdentityModel.Tokens;
using PSManagement.Application.Common.Services;
using PSManagement.Application.Contracts.Authentication;
using PSManagement.Application.Contracts.Authorization;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
namespace PSManagement.Infrastructure.Authentication
{
......@@ -22,7 +19,7 @@ namespace PSManagement.Infrastructure.Authentication
_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(
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