Skip to content

Commit

Permalink
feat(Register): register management created (#7)
Browse files Browse the repository at this point in the history
* fix(User):add exception for login

* feat(UserRegister):solve confilict

* feat(Register User):add JWT Validation

* feat(User):delete extra line in login method

* feat(user):add jwt middleware

* fix(user): jwt middleware

* fix(user): login

* feat(User): Add register.

* fix(user): login

* fix(User) : change structure of database

* fix(User): inner Exception

* fix(User): jwt problem and permission api

* fix(User): return login api

* fix(User): fix retutn of login api

* fix(User): fix some conflicts

* fix(User): change some method of testProject

---------

Co-authored-by: AmirReza <[email protected]>
Co-authored-by: K-Kabiri <[email protected]>
  • Loading branch information
3 people authored Aug 16, 2024
1 parent 0e022b1 commit 97b3e8d
Show file tree
Hide file tree
Showing 39 changed files with 625 additions and 396 deletions.
6 changes: 6 additions & 0 deletions AnalysisData/AnalysisData.sln.DotSettings.user
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,11 @@
&lt;TestAncestor&gt;&#xD;
&lt;TestId&gt;xUnit::9AEC1F3F-B1B3-47C1-82D4-E432E2D77E0E::net8.0::TestProject.Repository.RoleRepository.RoleRepositoryTests.AddRole_ShouldAddsRoleToDatabase_Whenever&lt;/TestId&gt;&#xD;
&lt;/TestAncestor&gt;&#xD;
&lt;/SessionState&gt;</s:String>
<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=c8b452a4_002D3e52_002D45a2_002D959c_002Dbbbf101ed826/@EntryIndexedValue">&lt;SessionState ContinuousTestingMode="0" IsActive="True" Name="All tests from &amp;lt;TestProject&amp;gt;" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"&gt;&#xD;
&lt;Project Location="C:\Users\Mahdi\Desktop\New folder (2)\Summer1403-Project-Group03-Backend\AnalysisData\TestProject" Presentation="&amp;lt;TestProject&amp;gt;" /&gt;&#xD;
&lt;/SessionState&gt;</s:String>
<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=ff0aa496_002Df562_002D44d7_002Db40c_002D780e81cc354b/@EntryIndexedValue">&lt;SessionState ContinuousTestingMode="0" Name="All tests from &amp;lt;TestProject&amp;gt; #2" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"&gt;&#xD;
&lt;Project Location="C:\Users\Mahdi\Desktop\New folder (2)\Summer1403-Project-Group03-Backend\AnalysisData\TestProject" Presentation="&amp;lt;TestProject&amp;gt;" /&gt;&#xD;
&lt;/SessionState&gt;</s:String></wpf:ResourceDictionary>

4 changes: 0 additions & 4 deletions AnalysisData/AnalysisData/AnalysisData.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,6 @@
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.0.1" />
</ItemGroup>

<ItemGroup>
<Folder Include="Repository\" />
</ItemGroup>

<ItemGroup>
<EmbeddedResource Update="Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
Expand Down
32 changes: 29 additions & 3 deletions AnalysisData/AnalysisData/Controllers/UserController.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
using System.Security.Claims;
using AnalysisData.Services;
using AnalysisData.UserManage.LoginModel;
using AnalysisData.UserManage.RegisterModel;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace AnalysisData.Controllers;
Expand All @@ -8,15 +11,38 @@ namespace AnalysisData.Controllers;
public class UserController : ControllerBase
{
private readonly IUserService _userService;
private readonly IPermissionService _permissionService;

public UserController(IUserService userService)
public UserController(IUserService userService,IPermissionService permissionService)
{
_userService = userService;
_permissionService = permissionService;
}
[HttpPost("login")]
public IActionResult Login([FromBody] UserLoginModel userLoginModel)
{
var userRoles = _userService.Login(userLoginModel);
return Ok(new { roles = userRoles });
var user = _userService.Login(userLoginModel);
return Ok(new { user.Result.FirstName , user.Result.LastName , user.Result.ImageURL });
}
[Authorize(Roles = "admin")]
[HttpPost("register")]
public async Task<IActionResult> Register([FromBody] UserRegisterModel userRegisterModel)
{
var check = await _userService.Register(userRegisterModel);
if (check)
{
return Ok("success");
}

return NotFound("not success");
}


[HttpGet("permissions")]
public IActionResult GetPermissions()
{
var userClaims = User;
var permission = _permissionService.GetPermission(userClaims);
return Ok(new { permission });
}
}
4 changes: 2 additions & 2 deletions AnalysisData/AnalysisData/CookieService/CookieService.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using AnalysisData.CookieSevice.abstractions;
using AnalysisData.CookieService.abstractions;

namespace AnalysisData.CookieSevice;
namespace AnalysisData.CookieService;

public class CookieService : ICookieService
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace AnalysisData.CookieSevice.abstractions;
namespace AnalysisData.CookieService.abstractions;

public interface ICookieService
{
Expand Down
5 changes: 1 addition & 4 deletions AnalysisData/AnalysisData/Data/ApplicationDbContext.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using AnalysisData.UserManage.Model;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;

namespace AnalysisData.Data;

Expand All @@ -9,9 +8,7 @@ public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}

public DbSet<User> Users { get; set; }
public DbSet<Role> Roles { get; set; }
public DbSet<UserRole> UserRoles { get; set; }

}
8 changes: 8 additions & 0 deletions AnalysisData/AnalysisData/Exception/DuplicateUserException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace AnalysisData.Exception;

public class DuplicateUserException : System.Exception
{
public DuplicateUserException() : base(Resources.DuplicateUserException)
{
}
}
10 changes: 10 additions & 0 deletions AnalysisData/AnalysisData/Exception/InvalidPasswordException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace AnalysisData.Exception;
using System;


public class InvalidPasswordException : Exception
{
public InvalidPasswordException() : base(Resources.InvalidPasswordException)
{
}
}
9 changes: 9 additions & 0 deletions AnalysisData/AnalysisData/Exception/NotFoundUserException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace AnalysisData.Exception;
using System;

public class NotFoundUserException : Exception
{
public NotFoundUserException() : base(Resources.NotFoundUserException)
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace AnalysisData.Exception;

public class PasswordMismatchException : System.Exception
{
public PasswordMismatchException() : base(Resources.PasswordMismatchException )
{
}
}
8 changes: 8 additions & 0 deletions AnalysisData/AnalysisData/Exception/RoleNotFoundException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace AnalysisData.Exception;

public class RoleNotFoundException : System.Exception
{
public RoleNotFoundException() : base(Resources.RoleNotFoundException)
{
}
}
22 changes: 9 additions & 13 deletions AnalysisData/AnalysisData/JwtService/JwtService.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using AnalysisData.JwtService.abstractions;
using AnalysisData.Repository.RoleRepository.Abstraction;
using AnalysisData.Repository.UserRepository.Abstraction;
using Microsoft.IdentityModel.Tokens;
Expand All @@ -11,30 +12,25 @@ public class JwtService : IJwtService
{
private readonly IConfiguration _configuration;
private readonly IUserRepository _userRepository;
private readonly IRoleRepository _roleRepository;


public JwtService(IConfiguration configuration , IUserRepository userRepository,IRoleRepository roleRepository)

public JwtService(IConfiguration configuration , IUserRepository userRepository)
{
_configuration = configuration;
_userRepository = userRepository;
_roleRepository = roleRepository;
}

public async Task<string> GenerateJwtToken(string userName)
{
var user =await _userRepository.GetUser(userName);
var roles = user.UserRoles;
var claims = new List<Claim>
{
new Claim("Name", userName),
new Claim("username", user.Username),
new Claim("firstname", user.FirstName),
new Claim("lastname", user.LastName),
new Claim(ClaimTypes.Email, user.Email),
new Claim(ClaimTypes.MobilePhone, user.PhoneNumber),
new Claim(ClaimTypes.Role, user.Role.RoleName),
};
foreach (var role in roles)
{
var result = await _roleRepository.GetRole(role.Id);
claims.Add(new Claim("Roles", result.RoleName));
}

var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:Key"]));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace AnalysisData.JwtService;
namespace AnalysisData.JwtService.abstractions;

public interface IJwtService
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
using System.ComponentModel.DataAnnotations;
using Microsoft.IdentityModel.Tokens;

namespace AnalysisData.Exception;

public class ExceptionHandlingMiddleware
{
private readonly RequestDelegate _next;

public ExceptionHandlingMiddleware(RequestDelegate next)
{
_next = next;
}

public async Task InvokeAsync(HttpContext httpContext)
{
try
{
await _next(httpContext);
}
catch (NotFoundUserException ex)
{
await HandleExceptionAsync(httpContext, ex, StatusCodes.Status404NotFound);
}
catch (UnauthorizedAccessException ex)
{
await HandleExceptionAsync(httpContext, ex, StatusCodes.Status401Unauthorized);
}
catch (ValidationException ex)
{
await HandleExceptionAsync(httpContext, ex, StatusCodes.Status400BadRequest);
}
catch (TimeoutException ex)
{
await HandleExceptionAsync(httpContext, ex, StatusCodes.Status408RequestTimeout);
}
catch (SecurityTokenExpiredException ex)
{
await HandleExceptionAsync(httpContext, ex, StatusCodes.Status401Unauthorized);
}
catch (SecurityTokenInvalidSignatureException ex)
{
await HandleExceptionAsync(httpContext, ex, StatusCodes.Status401Unauthorized);
}
catch (SecurityTokenInvalidAudienceException ex)
{
await HandleExceptionAsync(httpContext, ex, StatusCodes.Status401Unauthorized);
}
catch (InvalidPasswordException ex)
{
await HandleExceptionAsync(httpContext, ex, StatusCodes.Status401Unauthorized);
}
catch (DuplicateUserException ex)
{
await HandleExceptionAsync(httpContext, ex, StatusCodes.Status401Unauthorized);
}
catch (PasswordMismatchException ex)
{
await HandleExceptionAsync(httpContext, ex, StatusCodes.Status401Unauthorized);
}

{}

}

private Task HandleExceptionAsync(HttpContext context, System.Exception exception, int statusCode)
{
context.Response.ContentType = "application/json";
context.Response.StatusCode = statusCode;

var response = new
{
statusCode = statusCode,
message = exception.Message,
};

return context.Response.WriteAsync(System.Text.Json.JsonSerializer.Serialize(response));
}
}
62 changes: 62 additions & 0 deletions AnalysisData/AnalysisData/MiddleWare/JwtMiddleware.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
using System.IdentityModel.Tokens.Jwt;
using System.Text;
using Microsoft.IdentityModel.Tokens;

namespace AnalysisData;

public class JwtMiddleware
{
private readonly RequestDelegate _next;
private readonly string? _jwtSecret;

public JwtMiddleware(RequestDelegate next,IConfiguration configuration)
{
_next = next;
_jwtSecret = configuration["Jwt:Key"];
}


public async Task InvokeAsync(HttpContext context)
{
if (context.Request.Path.StartsWithSegments("/api/User/login") || context.Request.Path.StartsWithSegments("/api/User/register"))
{
await _next(context);
return;
}
var token = context.Request.Cookies["AuthToken"];
if (token != null)
{
try
{
AttachUserToContext(context, token);
}
catch
{
context.Response.StatusCode = StatusCodes.Status401Unauthorized;
await context.Response.WriteAsync("Invalid token.");
return;
}
}

await _next(context);
}

private void AttachUserToContext(HttpContext context, string token)
{
var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.ASCII.GetBytes(_jwtSecret);

var validationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = false,
ValidateAudience = false,
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero
};

var principal = tokenHandler.ValidateToken(token, validationParameters, out _);
context.User = principal;
}
}
Loading

0 comments on commit 97b3e8d

Please sign in to comment.